Como iterar (chaves, valores) em javascript?

335

Eu tenho um dicionário que tem o formato de

dictionary = {0: {object}, 1:{object}, 2:{object}}

Como posso percorrer este dicionário fazendo algo como

for((key,value) in dictionary){
  //Do stuff where key would be 0 and value would be the object
}
nbroeking
fonte
3
for (let [key, value] of Object.entries(obj)), preciso de Babel.
Elclanrs
1
@elclanrs Seu em ES2016 e ainda não é padronizado :-)
thefourtheye
2
Possível duplicata do For-each em uma matriz em JavaScript?
Sdc
@ Dooagain, não é uma matriz nesta questão.
zangw

Respostas:

480

tl; dr

  1. No ECMAScript 5, não é possível.
  2. No ECMAScript 2015, é possível com Maps.
  3. No ECMAScript 2017, ele estaria prontamente disponível.

ECMAScript 5:

Não, não é possível com objetos.

Você deve iterar com for..in, ou Object.keys, assim

for (var key in dictionary) {
    // check if the property/key is defined in the object itself, not in parent
    if (dictionary.hasOwnProperty(key)) {           
        console.log(key, dictionary[key]);
    }
}

Nota: A ifcondição acima é necessária, apenas se você desejar iterar as propriedades que são dictionarypróprias do objeto. Porquefor..in irá percorrer todas as propriedades enumeráveis ​​herdadas.

Ou

Object.keys(dictionary).forEach(function(key) {
    console.log(key, dictionary[key]);
});

ECMAScript 2015

No ECMAScript 2015, você pode usar Mapobjetos e iterá-los Map.prototype.entries. Citando um exemplo dessa página,

var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");

var mapIter = myMap.entries();

console.log(mapIter.next().value); // ["0", "foo"]
console.log(mapIter.next().value); // [1, "bar"]
console.log(mapIter.next().value); // [Object, "baz"]

Ou itere com for..of, assim

'use strict';

var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");

for (const entry of myMap.entries()) {
  console.log(entry);
}

Resultado

[ '0', 'foo' ]
[ 1, 'bar' ]
[ {}, 'baz' ]

Ou

for (const [key, value] of myMap.entries()) {
  console.log(key, value);
}

Resultado

0 foo
1 bar
{} baz

ECMAScript 2017

O ECMAScript 2017 introduziria uma nova função Object.entries. Você pode usar isso para iterar o objeto conforme desejado.

'use strict';

const object = {'a': 1, 'b': 2, 'c' : 3};
for (const [key, value] of Object.entries(object)) {
  console.log(key, value);
}

Resultado

a 1
b 2
c 3
thefourtheye
fonte
1
Uma dúvida básica aqui. Cheguei aqui procurando como fazer isso no node.js, que é javascript no lado do servidor. Como sei qual versão do ES se aplica no meu caso. Além disso, no caso de usuários regulares de javascript, qual é a maneira correta de oferecer suporte, pois eu entendo que a versão ES depende do navegador do cliente?
Sandeepan Nath
2
@SandeepanNath Você pode usar sites como node.green para saber se um recurso ES específico é suportado no seu Node.js. No que diz respeito aos navegadores, as pessoas geralmente segmentam a versão que é amplamente suportada, neste caso, o ES5. Além disso, os transpilers (como o Babel ) ajudam a converter o código ES2015 + em ES5.
thefourtheye
1
Eu gosto de Object.keys(dictionary).forEach(function(key) {…muito legível e compatível.
Ctrl-alt-delor
6
Object.entries(object).forEach(([key, val]) => {...});
Krimson
A solução ECMAScript 2015 acima lançou "TypeScript e Iterator: o tipo 'IterableIterator <T>' não é um tipo de matriz", mas o simples myMap (). Foreach () funcionou bem.
ttugates
60

Tente o seguinte:

dict = {0:{1:'a'}, 1:{2:'b'}, 2:{3:'c'}}
for (var key in dict){
  console.log( key, dict[key] );
}

0 Object { 1="a"}
1 Object { 2="b"}
2 Object { 3="c"}
alex10
fonte
42

O Object.entries()método foi especificado no ES2017 (e é suportado em todos os navegadores modernos ):

for (const [ key, value ] of Object.entries(dictionary)) {
    // do something with `key` and `value`
}

Explicação:

  • Object.entries()leva um objeto como { a: 1, b: 2, c: 3 }e transforma-lo em uma matriz de pares chave-valor: [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ].

  • Com for ... ofnós podemos fazer um loop sobre as entradas da matriz criada.

  • Como temos a garantia de que cada um dos itens da matriz iterada é ela própria uma matriz de duas entradas, podemos usar a desestruturação para atribuir diretamente variáveis keye valueao seu primeiro e segundo itens.

Loilo
fonte
O triste é que as pessoas ainda usam Internet Explorer
Edward
Estou dolorosamente consciente. Babel e polyfill.io resolvem isso, mas está longe de ser agradável.
Loilo 6/12/19
19

Você pode fazer algo assim:

dictionary = {'ab': {object}, 'cd':{object}, 'ef':{object}}
var keys = Object.keys(dictionary);

for(var i = 0; i < keys.length;i++){
   //keys[i] for key
   //dictionary[keys[i]] for the value
}
Dhaval Chaudhary
fonte
3
Lindo! Adoro como sua resposta funciona no ECMAscript 5, apesar da resposta aceita e mais votada dizer que não é possível. Você merece muito mais votos positivos.
liljoshu
18

Tente o seguinte:

var value;
for (var key in dictionary) {
    value = dictionary[key];
    // your code here...
}
AMACB
fonte
9

BEM-VINDO A 2020 * Baba no ES6 *

Há algumas respostas bem antigas aqui - aproveite a desestruturação. Na minha opinião, essa é sem dúvida a melhor (muito legível) maneira de iterar um objeto.

Object.entries(myObject).forEach(([k,v]) => {
    console.log("The key: ",k)
    console.log("The value: ",v)
})
Steve
fonte
Apenas uma observação: se você substituir forEachpelo item mapacima, será possível agregar valores. mapretornará uma lista dos referidos valores, simplificando potencialmente o código de outras maneiras.
Lazerbeak12345
1

usando swagger-ui.js

você consegue fazer isso -

_.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
    console.log(n, key);
 });
deeshank
fonte
0

Você pode usar o script abaixo.

var obj={1:"a",2:"b",c:"3"};
for (var x=Object.keys(obj),i=0;i<x.length,key=x[i],value=obj[key];i++){
    console.log(key,value);
}

saídas
1 a
2 b
c 3

Michael Piper
fonte
#will output # 3 # 1 a # 2 b
Michael Piper
4
Considere adicionar uma explicação à sua resposta, apenas o código é menos útil. Além disso, você pode editar sua resposta, os comentários não são destinadas a ser uma extensão para a resposta da maneira que você está usando-os
Viktor
0

Como uma melhoria na resposta aceita, para reduzir o aninhamento, você pode fazer isso, desde que a chave não seja herdada:

for (var key in dictionary) {
    if (!dictionary.hasOwnProperty(key)) {
        continue;
    }
    console.log(key, dictionary[key]);
}

Editar: informações sobre Object.hasOwnProperty aqui

kloddant
fonte