Como converter um objeto {} em uma matriz [] de pares de valor-chave em JavaScript


243

Eu quero converter um objeto como este:

{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

em uma matriz de pares de valores-chave como este:

[[1,5],[2,7],[3,0],[4,0]...].

Como posso converter um objeto em uma matriz de pares de valores-chave em JavaScript?

Respostas:


428

Você pode usar Object.keys()e map()fazer isso

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [Number(key), obj[key]];
});

console.log(result);


6
@blvckasvp Você está usando números como teclas? Caso contrário, quando tentar converter sua chave em um número, ela falhará e retornará NaN. Se você quiser usar cordas como suas chaves, altere o retorno de [Number(key), obj[key]]a [key, obj[key]]ou usar o Object.entriescomo @Pila sugeriu em sua resposta
scottbot95

123

A melhor maneira é fazer:

var obj ={"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10"‌​:0,"11":0,"12":0} 
Object.entries(obj);

A chamada entries, como mostrado aqui, retornará [key, value]pares, conforme solicitado pelo solicitante.

Como alternativa, você poderia chamar Object.values(obj), o que retornaria apenas valores.


6
Caros desenvolvedores, verifique a tabela de compatibilidade do ECMA antes de adotar essas boas funções que são compatíveis apenas com navegadores lançados minutos atrás.
andreszs 18/10/19

8
@andreszs Consulte Posso usar a tabela, se você não se importa em desistir do suporte ao IE (e em 2019, espero que você não goste da sua sanidade), então você está pronto para ir. O FF 47 é de junho de 2016 e o ​​Chrome 54 é de outubro do mesmo ano, Edge 14 de agosto. Não exatamente a alguns minutos atrás.
Kyll

FYI: Object.entries retornará [key, value], mas a chave será uma string e o valor será diferente.
SHAHBAZ 25/04

61

Object.entries()retorna uma matriz cujos elementos são matrizes correspondentes aos [key, value]pares de propriedades enumeráveis encontrados diretamente object. A ordem das propriedades é a mesma que a especificada repetindo manualmente os valores das propriedades do objeto.

- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Description

A Object.entriesfunção retorna quase a saída exata que você está solicitando, exceto que as teclas são cadeias de caracteres em vez de números.

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

console.log(Object.entries(obj));

Se você precisar que as chaves sejam números, poderá mapear o resultado para uma nova matriz com uma função de retorno de chamada que substitua a chave em cada par por um número coagido a ela.

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
    const entries = Object.entries(input);
    return entries.map(entry => Object.assign(entry, { 0: +entry[0] }));
}

console.log(toNumericPairs(obj));

Eu uso uma função de seta e Object.assignpara o retorno de chamada do mapa no exemplo acima, para que eu possa mantê-lo em uma instrução, aproveitando o fato de Object.assignretornar o objeto ao qual está sendo atribuído, e o valor de retorno de uma única função de seta de instrução é o resultado da instrução.

Isso é equivalente a:

entry => {
    entry[0] = +entry[0];
    return entry;
}

Conforme mencionado por @TravisClarke nos comentários, a função de mapa pode ser reduzida para:

entry => [ +entry[0], entry[1] ]

No entanto, isso criaria uma nova matriz para cada par de valores-chave, em vez de modificar a matriz existente, dobrando a quantidade de matrizes de pares de valores-chave criadas. Enquanto a matriz de entradas originais ainda estiver acessível, ela e suas entradas não serão coletadas como lixo.

Agora, mesmo que o uso do método local ainda use duas matrizes que contêm os pares de valores-chave (as matrizes de entrada e saída), o número total de matrizes muda apenas uma. As matrizes de entrada e saída não são realmente preenchidas com matrizes, mas as referências a matrizes e essas referências ocupam uma quantidade insignificante de espaço na memória.

  • A modificação de cada par de valores-chave no local resulta em uma quantidade insignificante de aumento de memória, mas requer a digitação de mais alguns caracteres.
  • Criar uma nova matriz para cada par de valores-chave resulta na duplicação da quantidade de memória necessária, mas requer digitação de alguns caracteres a menos.

Você poderia dar um passo adiante e eliminar completamente o crescimento modificando a matriz de entradas no local, em vez de mapear para uma nova matriz:

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
  const entries = Object.entries(obj);
  entries.forEach(entry => entry[0] = +entry[0]);
  return entries;
}

console.log(toNumericPairs(obj));


1
Eu gosto da abordagem funcional. Como alternativa mais curta:Object.entries(obj).map(e => [+e[0], e[1]]);
Travis Clarke

20

Para recapitular algumas dessas respostas agora em 2018, onde ES6 é o padrão.

Começando com o objeto:

let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
  • Apenas obtendo cegamente os valores em uma matriz, não se importa com as chaves:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.values(obj));
//[9,8,7,6,5,4,3,2,1,0,5]

  • Simples obtendo os pares em uma matriz:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj));
//[["1",9],["2",8],["3",7],["4",6],["5",5],["6",4],["7",3],["8",2],["9",1],["10",0],["12",5]]

  • O mesmo que o anterior, mas com teclas numéricas em cada par:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).map(([k,v])=>[+k,v]));
//[[1,9],[2,8],[3,7],[4,6],[5,5],[6,4],[7,3],[8,2],[9,1],[10,0],[12,5]]

  • Usando a propriedade do objeto como chave para uma nova matriz (poderia criar matrizes esparsas):

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).reduce((ini,[k,v])=>(ini[k]=v,ini),[]));
//[undefined,9,8,7,6,5,4,3,2,1,0,undefined,5]

Este último método, também poderia reorganizar a ordem da matriz, dependendo do valor das chaves. Às vezes, esse pode ser o comportamento desejado (às vezes não). Mas a vantagem agora é que os valores são indexados no slot de matriz correto, essencial e trivial para fazer pesquisas nele.

  • Mapa em vez de matriz

Por fim (não faz parte da pergunta original, mas para completar), se você precisar pesquisar facilmente usando a chave ou o valor, mas não desejar matrizes esparsas, sem duplicatas e sem reordenar sem a necessidade de converter em chaves numéricas ( mesmo pode acessar chaves muito complexas), então matriz (ou objeto) não é o que você precisa. Em Mapvez disso, vou recomendar :

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true

2
O quarto ponto em diante é totalmente irrelevante para a pergunta, e o restante da sua resposta está apenas resumindo as três principais respostas aqui. Essa resposta não traz nada à discussão que ainda não estava aqui ou que não é completamente irrelevante.

Sim, como estado da primeira linha, este é um resumo das respostas e, em seguida, atualize-as para usar as técnicas modernas do ES6 em vez das funções de golpe completo. A quarta resposta é útil quando você move matrizes JSON de uma linguagem que suporta matrizes associativas (por exemplo, PHP).
CarlosH.

Todos os métodos fornecidos aqui já foram fornecidos em sua forma simples em duas das três principais respostas; eles não estão em funções; portanto, não sei o que você está fazendo aí. Quanto ao quarto, como eu disse, é completamente irrelevante para a pergunta. Pode ser relevante para uma pergunta diferente, mas não para esta. Independentemente disso, JSON é JSON, seja ele criado usando PHP, JavaScript ou Haskell.

18

Mais uma solução, se Object.entriesnão funcionar para você.

const obj = {
      '1': 29,
      '2': 42
    };
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);


1
Isso funcionou para mim. Ocorreu um problema em que a importação de JSON adicionou índices que impossibilitavam o uso do loop ngFor ng da Angulars. Isso removeu os índices enquanto preservava a estrutura.
RAC

@RAC +1 por usar "índices" em vez de "índices". Tradições inglesas arcaicas (isto é, arbitrárias e sem sentido) desviantes!
Venryx 8/01/19

12

No Ecmascript 6,

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

var res = Object.entries(obj);

console.log(res);

violino


Não sei por que isso foi rebaixado, funcionou perfeitamente bem
sMyles

1
Não reduzi o voto, mas observe que a .map((value)=>(value))parte não tem sentido - apenas retorna uma matriz de entrada exatamente equivalente à obtida na Object.entries(obj)chamada.
Venryx 8/01/19

8

Uso Object.keyse Array#mapmétodos.

var obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};
// get all object property names
var res = Object.keys(obj)
  // iterate over them and generate the array
  .map(function(k) {
    // generate the array element 
    return [+k, obj[k]];
  });

console.log(res);


7

Use Object.entriespara obter cada elemento do Object no key & valueformato, e mapatravés deles como este:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

var res = Object.entries(obj).map(([k, v]) => ([Number(k), v]));

console.log(res);

Mas, se você tiver certeza de que as chaves estarão em ordem progressiva, poderá usar Object.valuese Array#mapfazer algo assim:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}; 

                        // idx is the index, you can use any logic to increment it (starts from 0)
let result = Object.values(obj).map((e, idx) => ([++idx, e]));

console.log(result);


5

Se você estiver usando o lodash, pode ser tão simples quanto isto:

var arr = _.values(obj);

5

Com o lodash, além da resposta fornecida acima, você também pode ter a chave na matriz de saída.

Sem as chaves do objeto na matriz de saída

para:

const array = _.values(obj);

Se obj é o seguinte:

{ art”: { id: 1,  title: aaaa }, fiction”: { id: 22,  title: 7777”} }

A matriz será:

[ { id: 1, title: aaaa }, { id: 22, title: 7777 } ]

Com as chaves do objeto na matriz de saída

Se você escrever em vez disso ('gênero' é uma sequência que você escolher):

const array= _.map(obj, (val, id) => {
    return { ...val, genre: key };
  });

Você vai ter:

[ 
  { id: 1, title: aaaa , genre: art”}, 
  { id: 22, title: 7777”, genre: fiction }
]

4

Eu sugeriria esta solução mais simples de usar Object.entries()

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result =Object.entries(obj)

console.log(result);


1

Você pode usar Object.values([]), pode precisar deste polyfill se ainda não:

const objectToValuesPolyfill = (object) => {
  return Object.keys(object).map(key => object[key]);
};
Object.values = Object.values || objectToValuesPolyfill;

https://stackoverflow.com/a/54822153/846348

Então você pode simplesmente fazer:

var object = {1: 'hello', 2: 'world'};
var array = Object.values(object);

Lembre-se de que matrizes em js podem usar apenas teclas numéricas; portanto, se você usou algo mais no objeto, elas se tornarão `` 0,1,2 ... x``

Pode ser útil remover duplicatas, por exemplo, se você tiver uma chave exclusiva.

var obj = {};
object[uniqueKey] = '...';

0

Use para em

var obj = { "10":5, "2":7, "3":0, "4":0, "5":0, "6":0, "7":0,
            "8":0, "9":0, "10":0, "11":0, "12":0 };

var objectToArray = function(obj) {
    var _arr = [];

    for (var key in obj) {
        _arr.push([key, obj[key]]);
    }
    return _arr;
}

console.log(objectToArray(obj));

0

Objeto de conversão recursiva em matriz

function is_object(mixed_var) {
    if (mixed_var instanceof Array) {
        return false;
    } else {
        return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
    }
}


function objectToArray(obj) {
    var array = [], tempObject;
    for (var key in obj) {

        tempObject = obj[key];

        if (is_object(obj[key])) {
            tempObject = objectToArray(obj[key]);
        }
        array[key] = tempObject;
    }
    return array;
}

0

Podemos mudar o número para o tipo String para Key, como abaixo:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [String(key), obj[key]];
});
    
console.log(result);


0

Esta é a minha solução, tenho o mesmo problema e parece que esta solução funciona para mim.

yourObj = [].concat(yourObj);

0

Esta é minha implementação simples de barebone:

let obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};    

const objectToArray = obj => {
      let sol = [];
      for (key in obj) {
        sol.push([key, obj[key]]);
      }
      return sol;
    };

objectToArray(obj)

0

Solução simples

`

var result = Object.keys(records).map(function (value) {
         return { [value]: records[value] };
});
console.log(result);


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.