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?

Soptareanu Alex
fonte

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);

Nenad Vracar
fonte
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.

Pila
fonte
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));


fonte
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
CarlosH.
fonte
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);

bigh_29
fonte
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

Pandem Reddy de Nageshwar
fonte
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);

Pranav C Balan
fonte
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);

Barba Negra
fonte
5

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

var arr = _.values(obj);
Adam Boostani
fonte
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 }
]
Yossi
fonte
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);

Pilha da ironia
fonte
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] = '...';
OZZIE
fonte
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));
wkyniston
fonte
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;
}
Marina Lebedeva
fonte
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);

Nagnath Mungade
fonte
0

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

yourObj = [].concat(yourObj);
Qui-Gon Jinn
fonte
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)
Ketan Ramteke
fonte
0

Solução simples

`

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

Folorunso
fonte
-1

você pode usar _.castArray (obj) .

exemplo: _.castArray({ 'a': 1 }); // => [{ 'a': 1 }]

Chopper Lee
fonte