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.