¿Cómo iterar (claves, valores) en javascript?

335

Tengo un diccionario que tiene el formato de

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

¿Cómo puedo iterar a través de este diccionario haciendo algo como

for((key,value) in dictionary){
  //Do stuff where key would be 0 and value would be the object
}
nbroeking
fuente
3
for (let [key, value] of Object.entries(obj))Necesito a Babel.
elclanrs
1
@elclanrs Está en ES2016 y aún no está estandarizado :-)
thefourtheye
2
¿Posible duplicado de For-each sobre una matriz en JavaScript?
sdc
@dooagain, no es una matriz en esta pregunta.
zangw

Respuestas:

480

tl; dr

  1. En ECMAScript 5, no es posible.
  2. En ECMAScript 2015, es posible con Maps.
  3. En ECMAScript 2017, estaría fácilmente disponible.

ECMAScript 5:

No, no es posible con objetos.

Deberías iterar con for..in, o Object.keys, así

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: La ifcondición anterior es necesaria, solo si desea iterar las propiedades que son dictionarypropias del objeto. Porque for..initerará a través de todas las propiedades enumerables heredadas.

O

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

ECMAScript 2015

En ECMAScript 2015, puede usar Mapobjetos e iterarlos Map.prototype.entries. Ejemplo de cita de esa 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"]

O iterar con for..of, así

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

Salida

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

O

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

Salida

0 foo
1 bar
{} baz

ECMAScript 2017

ECMAScript 2017 introduciría una nueva función Object.entries. Puede usar esto para iterar el objeto como desee.

'use strict';

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

Salida

a 1
b 2
c 3
thefourtheye
fuente
1
Una duda básica aquí. Aterricé aquí buscando cómo hacer esto en node.js, que es JavaScript en el lado del servidor. ¿Cómo sé qué versión de ES se aplica en mi caso? Además, en el caso de los usuarios habituales de javascript, ¿cuál es la forma correcta de soportar, ya que entiendo que la versión ES depende del navegador del cliente?
Sandeepan Nath
2
@SandeepanNath Puede usar sitios web como node.green para saber si una característica particular de ES es compatible con su Node.js. En lo que respecta a los navegadores, las personas generalmente apuntan a la versión que es ampliamente compatible, en este caso, ES5. Además de esto, los transpiladores (como Babel ) ayudan a convertir el código ES2015 + a ES5.
thefourtheye
1
Me gusta Object.keys(dictionary).forEach(function(key) {…muy legible y compatible.
ctrl-alt-delor
66
Object.entries(object).forEach(([key, val]) => {...});
Krimson
La solución ECMAScript 2015 anterior arrojó "TypeScript e Iterator: el tipo 'IterableIterator <T>' no es un tipo de matriz", pero simplemente ol myMap (). Foreach () funcionó bien.
ttugates
60

Prueba esto:

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
fuente
42

El Object.entries()método se ha especificado en ES2017 (y es compatible con todos los navegadores modernos ):

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

Explicación:

  • Object.entries()toma un objeto como { a: 1, b: 2, c: 3 }y lo convierte en un conjunto de pares de valores clave: [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ].

  • Con for ... ofpodemos recorrer las entradas de la matriz así creada.

  • Dado que tenemos la garantía de que cada uno de los elementos de la matriz iterada es en sí mismo una matriz de dos entradas, podemos usar la desestructuración para asignar directamente variables keyy valuea su primer y segundo elemento.

Loilo
fuente
Lo triste es que la gente todavía usa Internet Explorer
Edward
Estoy dolorosamente consciente. Babel y polyfill.io resuelven esto, pero está lejos de ser agradable.
Loilo
19

Puedes hacer algo como esto:

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
fuente
3
¡Hermoso! Me encanta cómo funciona su respuesta en ECMAscript 5 a pesar de la respuesta aceptada y más votada que dice que no es posible. Te mereces muchos más votos a favor.
liljoshu
18

Prueba esto:

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

BIENVENIDO A 2020 * Drools en ES6 *

Aquí hay algunas respuestas bastante antiguas: aproveche la desestructuración. En mi opinión, esta es sin duda la mejor manera (muy legible) de iterar un objeto.

Object.entries(myObject).forEach(([k,v]) => {
    console.log("The key: ",k)
    console.log("The value: ",v)
})
Steve
fuente
Solo una nota: si reemplaza forEachcon el mapanterior, entonces es posible agregar valores. mapluego devolverá una lista de dichos valores, lo que simplifica potencialmente el código de otras maneras.
Lazerbeak12345
1

usando swagger-ui.js

Puedes hacerlo -

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

Puedes usar el siguiente script.

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

salidas
1 a
2 b
c 3

Michael Piper
fuente
# salida #c 3 # 1 a # 2 b
Michael Piper
44
Considere agregar una explicación a su respuesta, el código solo es menos útil. Además, puede editar su respuesta, los comentarios no están destinados a ser una extensión de la respuesta en la forma en que los está utilizando
Viktor
0

Como una mejora a la respuesta aceptada, para reducir el anidamiento, puede hacer esto en su lugar, siempre que la clave no se herede:

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

Editar: información sobre Object.hasOwnProperty aquí

kloddant
fuente