Recorrer una matriz en JavaScript

3148

En Java, puede usar un forbucle para atravesar objetos en una matriz de la siguiente manera:

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

¿Puedes hacer lo mismo en JavaScript?

Mark Szymanski
fuente
55
Ok, entonces estoy un poco confundido, ¿está bien usar el bucle mejorado para cuando accedes a los objetos? ¿Y usar uno secuencial para llenar uno? ¿Es esto correcto?
Mark Szymanski
45
no, es realmente simple, los objetos de matriz tienen índices numéricos, por lo que desea iterar sobre esos índices en el orden numérico, un ciclo secuencial asegura que, el ciclo mejorado enumera las propiedades del objeto, sin un orden específico, y también enumera las propiedades heredadas. .. para iterar sobre matrices, los bucles secuenciales siempre se recomiendan ...for-in
CMS
2
relacionados - stackoverflow.com/questions/5349425/…
jondavidjohn
66
jsben.ch/#/Q9oD5 <= Aquí un punto de referencia de un montón de soluciones para recorrer los arreglos
EscapeNetscape
3
@CMS No, no es realmente simple. Es realmente simple en cualquier otro idioma. Es ridículamente complejo en JS, donde tienes iny ofeso puede usarse y hacer cosas diferentes. Entonces también tienes forEachy el bucle basado en índices feo y molesto. Todos los demás idiomas modernos hacen que recorrer una colección sea fácil y directo, sin sorpresas ni confusión. JS también podría, pero no lo hace.
jpmc26

Respuestas:

3966

Tienes varias opciones:

1. forBucle secuencial :

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

Pros

  • Funciona en todos los ambientes.
  • Puede usar breaky continuecontrolar las declaraciones de control

Contras

  • Demasiado detallado
  • Imperativo
  • Fácil de tener errores off-by-one (a veces también llamado error de publicación de valla )

2. Array.prototype.forEach

La especificación ES5 introdujo muchos métodos de matriz beneficiosos, uno de ellos, Array.prototype.forEachy nos proporciona una forma concisa de iterar sobre una matriz:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

Casi diez años después de la publicación de la especificación ES5 (diciembre de 2009), la han implementado casi todos los motores modernos en el escritorio, el servidor y los entornos móviles, por lo que es seguro usarlos.

Y con la sintaxis de la función de flecha ES6, es aún más sucinto:

array.forEach(item => console.log(item));

Las funciones de flecha también se implementan ampliamente a menos que planee admitir plataformas antiguas (por ejemplo, IE11); también estás seguro para ir.

Pros

  • Muy corto y conciso.
  • Declarativo

Contras

  • No se puede usar break/continue

Normalmente, puede reemplazar la necesidad de breaksalir de los bucles imperativos filtrando los elementos de la matriz antes de iterarlos, por ejemplo:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

Tenga en cuenta que si está iterando una matriz para construir otra matriz a partir de ella , debe usar map, he visto este antipatrón tantas veces.

Antipatrón:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

Caso de uso apropiado del mapa :

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

Además, si está intentando reducir la matriz a un valor, por ejemplo, desea sumar una matriz de números, debe usar el método de reducción .

Antipatrón:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

Uso adecuado de reducir :

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. for-ofDeclaración ES6

El estándar ES6 introduce el concepto de objetos iterables y define una nueva construcción para atravesar datos, la for...ofdeclaración.

Esta declaración funciona para cualquier tipo de objeto iterable y también para generadores (cualquier objeto que tenga una [Symbol.iterator]propiedad).

Los objetos de matriz son, por definición, iterables integrados en ES6, por lo que puede usar esta declaración en ellos:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

Pros

  • Puede iterar sobre una gran variedad de objetos.
  • Puede usar declaraciones de control de flujo normales ( break/ continue).
  • Útil para iterar valores asíncronos en serie.

Contras

No utilice for...in

@zipcodeman sugiere el uso de la for...indeclaración, pero para for-inevitar la iteración de matrices , esa declaración está destinada a enumerar las propiedades del objeto.

No debe usarse para objetos tipo matriz porque:

  • El orden de iteración no está garantizado; los índices de la matriz no se pueden visitar en orden numérico.
  • Las propiedades heredadas también se enumeran.

El segundo punto es que puede darle muchos problemas, por ejemplo, si extiende el Array.prototypeobjeto para incluir un método allí, esa propiedad también se enumerará.

Por ejemplo:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
    console.log(array[i]);
}

El código anterior consola registrará "a", "b", "c" y "foo!".

Eso será particularmente un problema si usa alguna biblioteca que depende en gran medida del aumento de prototipos nativos (como MooTools, por ejemplo).

La for-indeclaración como dije antes está ahí para enumerar las propiedades de los objetos, por ejemplo:

var obj = {
    "a": 1,
    "b": 2,
    "c": 3
};

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) { 
        // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
    }
}

En el ejemplo anterior, el hasOwnPropertymétodo le permite enumerar solo propiedades propias , eso es, solo las propiedades que tiene físicamente el objeto, sin propiedades heredadas.

Te recomendaría que leas el siguiente artículo:

CMS
fuente
21
Esta es la razón (por CMS él mismo) stackoverflow.com/questions/1885317/…
OscarRyz
15
@DoubleGras, creo que es una opinión que no todos comparten. Ver: stackoverflow.com/questions/5752906/… o groups.google.com/forum/?fromgroups#!topic/jsmentors/…
Matthijs Wessels
3
Cualquiera que piense que necesita almacenar en caché la longitud ... Vea mi respuesta, ni siquiera necesita acceder a ella una sola vez, y mucho menos almacenarla en caché: for (var i = 0, item; item = myStringArray [i]; i ++) {/ * use item here * /}
Stijn de Witt
15
@StijndeWitt No, porque que se rompe si tiene alguna "Falsey" los valores de la matriz: false, undefined, 0, "", NaN.
Phrogz
66
jsperf.com/caching-array-length/4 Aquí hay una prueba para ver si vale la pena almacenar en caché la longitud de una matriz en un bucle Javascript
Enrico
1116

Sí, suponiendo que su implementación incluya la for...of característica introducida en ECMAScript 2015 (la versión "Harmony") ... que es una suposición bastante segura en estos días.

Funciona así:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

O mejor aún, ya que ECMAScript 2015 también proporciona variables de ámbito de bloque:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

(La variable ses diferente en cada iteración, pero aún se puede declarar constdentro del cuerpo del bucle siempre que no se modifique allí).

Una nota sobre matrices dispersas: es posible que una matriz en JavaScript no almacene tantos elementos como lo informa su length; ese número reportado es simplemente uno mayor que el índice más alto en el que se almacena un valor. Si la matriz contiene menos elementos que los indicados por su longitud, se dice que es escasa . Por ejemplo, es perfectamente legítimo tener una matriz con elementos solo en los índices 3, 12 y 247; los s para cualquier elemento faltante, o solo desea procesar los elementos realmente presentes? Hay muchas aplicaciones para ambos enfoques; solo depende de para qué esté usando la matriz.length de dicha matriz se informa como 248, aunque en realidad solo almacena 3 valores. Si intenta acceder a un elemento en cualquier otro índice, la matriz parecerá tener el undefinedvalor allí. Entonces, cuando desea "recorrer" una matriz, tiene una pregunta que responder: ¿desea recorrer el rango completo indicado por su longitud y proceso?undefined

Si itera sobre una matriz con for... of, el cuerpo del bucle se ejecuta lengthveces y la variable de control de bucle se establece undefinedpara cualquier elemento que no esté realmente presente en la matriz. Dependiendo de los detalles de su código de "hacer algo con", ese comportamiento puede ser lo que desea, pero si no, debe usar un enfoque diferente.

Por supuesto, algunos desarrolladores no tienen más remedio que utilizar un enfoque diferente de todos modos, ya que por la razón que sea Están apuntando a una versión de JavaScript que todavía no es compatible for... of.

Mientras su implementación de JavaScript cumpla con la edición anterior de la especificación ECMAScript (que descarta, por ejemplo, las versiones de Internet Explorer anteriores a la 9), puede usar el Array#forEachmétodo iterador en lugar de un bucle. En ese caso, pasa una función para que se invoque en cada elemento de la matriz:

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

A diferencia de for... of, .forEachsolo llama a la función para elementos que están realmente presentes en la matriz. Si se pasa nuestra matriz hipotética con tres elementos y una longitud de 248, solo llamará a la función tres veces, no 248 veces. También distingue entre elementos faltantes y elementos que realmente están configurados en undefined; para este último, seguirá llamando a la función, pasando undefinedcomo argumento. Si esta es la forma en que desea manejar matrices dispersas, .forEachpuede ser el camino a seguir, incluso si sus ayudas de intérprete for... of.

La última opción, que funciona en todas las versiones de JavaScript, es un ciclo de conteo explícito . Simplemente cuenta de 0 a uno menos que la longitud y usa el contador como índice. El bucle básico se ve así:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  s = myStringArray[i];
  // ... do something with s ...
}

Una ventaja de este enfoque es que puede elegir cómo manejar matrices dispersas; el código anterior se ejecutará el cuerpo del bucle completo los lengthtiempos, con el sconjunto de undefinedde los elementos que faltan, al igual que for.. of. Si, en cambio, desea manejar solo los elementos realmente presentes de una matriz dispersa, como .forEach, puede agregar una inprueba simple en el índice:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

Asignar el valor de longitud a la variable local (en lugar de incluir la myStringArray.lengthexpresión completa en la condición del bucle) puede hacer una diferencia significativa en el rendimiento ya que omite una búsqueda de propiedad cada vez; usando Rhino en mi máquina, la aceleración es del 43%.

Puede ver el almacenamiento en caché de longitud realizado en la cláusula de inicialización del bucle, como esta:

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

El ciclo de conteo explícito también significa que tiene acceso al índice de cada valor, si lo desea. El índice también se pasa como un parámetro adicional a la función a la que se pasa forEach, por lo que también puede acceder a él de esa manera:

myStringArray.forEach( function(s, i) {
   // ... do something with s and i ...
});

for... ofno le da el índice asociado con cada objeto, pero siempre que el objeto sobre el que está iterando sea en realidad un Array( for... offunciona para otros tipos iterables que pueden no tener este método), puede usar la matriz # método de entradas para cambiarlo a una matriz de pares [índice, elemento] y luego iterar sobre eso:

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

La for... insintaxis mencionada por otros es para recorrer las propiedades de un objeto; Dado que una matriz en JavaScript es solo un objeto con nombres de propiedades numéricas (y una lengthpropiedad actualizada automáticamente ), teóricamente puede recorrer una matriz con ella. Pero el problema es que no se limita a los valores de las propiedades numéricas (recuerde que incluso los métodos son en realidad solo propiedades cuyo valor es un cierre), ni se garantiza que se repitan en orden numérico. Por lo tanto, la sintaxis for... no debe usarse para recorrer las matrices.in

Mark Reed
fuente
21
Tenga en cuenta que algunos intérpretes (por ejemplo, V8) almacenarán automáticamente en caché la longitud de la matriz si el código se llama suficientes veces y detecta que el ciclo no modifica la longitud. Si bien el almacenamiento en caché de la longitud sigue siendo bueno, es posible que no proporcione un aumento de velocidad cuando se invoca su código suficientes veces para marcar la diferencia.
Phrogz
2
@ mark-reed ¿Podría explicar por qué usó i in myStringArrayen su ejemplo? ¿Cómo puede ser eso falso?
Denis V
2
@DenisV: falso. a=[1,2,3,4]; delete a[2]; for (j in a) { console.log(j); } salidas 0, 1, 3 y 4. a.lengthsigue siendo 5.
Mark Reed
1
No estoy sugiriendo for j in a. Estoy demostrando que la inverificación no es redundante, como usted afirmó que era, mostrando todos los índices y mostrando que hay uno entre 0 y length-1que no está allí. También podría haber impreso 2 in a, que es false, a pesar del hecho de que dijiste que era imposible.
Mark Reed
2
@GrijeshChauhan - correcto. Por ejemplo, IE a través de la versión 8 no lo admite. Ver esta pregunta .
Mark Reed
442

Puede usar map, que es una técnica de programación funcional que también está disponible en otros lenguajes como Python y Haskell .

[1,2,3,4].map( function(item) {
     alert(item);
})

La sintaxis general es:

array.map(func)

En general func, tomaría un parámetro, que es un elemento de la matriz. Pero en el caso de JavaScript, puede tomar un segundo parámetro, que es el índice del elemento, y un tercer parámetro, que es la matriz misma.

El valor de retorno de array.mapes otra matriz, por lo que puede usarlo así:

var x = [1,2,3,4].map( function(item) {return item * 10;});

Y ahora x es [10,20,30,40].

No tiene que escribir la función en línea. Podría ser una función separada.

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

que sería equivalente a:

 for (item in my_list) {item_processor(item);}

Excepto que no entiendes el new_list.

Hasen
fuente
77
No, pero puede ser más poderoso. mira
hasen
97
Ese ejemplo particular probablemente se implementa mejor usando Array.forEach. mapes para generar una nueva matriz.
harto
21
@hasen, el Array.prototype.mapmétodo es parte del Estándar ECMAScript 5th Edition, aún no está disponible en todas las implementaciones (por ejemplo, IE carece de él), también para iterar sobre una matriz, creo que el Array.prototype.forEachmétodo es más semánticamente correcto ... también, por favor, no t sugiera la declaración for-in, vea mi respuesta para más detalles :)
CMS
3
La diferencia entre forEachy mapes que el primero no devuelve los resultados de la iteración. map(a veces también conocido como collect, pero muy diferente de apply) es expresamente para transformar cada elemento de una matriz en un resultado correspondiente; es un mapeo 1 a 1 , de ahí el nombre. Es parte de toda una familia de operaciones que incluyen reduce(que produce un solo resultado de toda la matriz) y filter(que produce un subconjunto de la matriz original) y así sucesivamente. Mientras que forEachsolo hace algo con cada elemento, la semántica no se especifica.
Mark Reed
44
Voto negativo porque si no estás mapeando algo, entonces usar [] .map es engañoso. [] .forEach tiene sentido semántico y también pasa los mismos tres argumentos a la función.
gengkev
120

En JavaScript no es recomendable recorrer un Array con un ciclo for-in, pero es mejor usar un forciclo como:

for(var i=0, len=myArray.length; i < len; i++){}

También está optimizado ("almacenamiento en caché" de la longitud de la matriz). Si desea obtener más información, lea mi publicación sobre el tema .

sebarmeli
fuente
2
myArray.forEach (function (obj) {}); sigue siendo el mejor
Jan Sverre
una pequeña mejora: podría usar en ++ilugar dei++
roberkules
14
++ies una optimización de la vieja escuela que los compiladores modernos hacen por ti en un ciclo for desde hace mucho tiempo :) stackoverflow.com/a/1547433/1033348
ngryman
66
Tienes que tener cuidado al usar este bucle. Comencé a usarlo y tuve un error difícil de rastrear debido a un error que cometí. Si anidas dos bucles como este: jsfiddle.net/KQwmL/1 . Debe tener cuidado de nombrar la variable var de manera diferente en los dos bucles, de lo contrario el segundo bucle sobrescribirá la primera len.
Rui Marques
1
Rui Marques: puede nombrar su variable i_stopo en i_endlugar de len. Es igual de legible (¡si no más!), Y naturalmente evitarás este tipo de problema (ya que tu otro bucle se volverá, por ejemplo j_stop).
Chip Hogg el
119

para (vamos a myStringArray) {

(Responde directamente a tu pregunta: ¡ahora puedes!)

La mayoría de las otras respuestas son correctas, pero no mencionan (a partir de este escrito) que ECMA Script  6  2015 está trayendo un nuevo mecanismo para hacer la iteración, el for..ofciclo.

Esta nueva sintaxis es la forma más elegante de iterar una matriz en javascript (siempre que no necesite el índice de iteración).

Actualmente funciona con Firefox 13+, Chrome 37+ y no funciona de forma nativa con otros navegadores (consulte la compatibilidad del navegador a continuación). Afortunadamente, tenemos compiladores JS (como Babel ) que nos permiten usar las características de la próxima generación hoy.

También funciona en Node (lo probé en la versión 0.12.0).

Iterando una matriz

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

Iterando una matriz de objetos

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

Iterando un generador:

(ejemplo extraído de https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of )

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

Tabla de compatibilidad: http://kangax.github.io/es5-compat-table/es6/#For..of bucles

Especificaciones: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}

Marlon Bernardes
fuente
Si está utilizando ES6, sugeriría en const slugar devar s
joeytwiddle
En mis pruebas en matrices grandes, el uso var s of arres casi el doble (1.9x) del tiempo de ejecución en comparación con el uso de un contador simple para bucle y la recuperación de elementos por índice en nodejs
theferrit32
¿Por qué esas cosas raras en la primera y última línea?
Peter Mortensen
91

Opera, Safari, Firefox y Chrome ahora comparten un conjunto de métodos Array mejorados para optimizar muchos bucles comunes.

Es posible que no los necesite todos, pero pueden ser muy útiles, o lo serían si todos los navegadores los admitieran.

Mozilla Labs publicó los algoritmos que ellos y WebKit usan, para que pueda agregarlos usted mismo.

filter devuelve una matriz de elementos que satisfacen alguna condición o prueba.

cada devuelve verdadero si cada miembro de la matriz pasa la prueba.

algunos devuelve verdadero si alguno pasa la prueba.

forEach ejecuta una función en cada miembro de la matriz y no devuelve nada.

map es como forEach, pero devuelve una matriz de los resultados de la operación para cada elemento.

Todos estos métodos toman una función para su primer argumento y tienen un segundo argumento opcional, que es un objeto cuyo alcance desea imponer a los miembros de la matriz a medida que recorren la función.

Ignóralo hasta que lo necesites.

indexOf y lastIndexOf encuentran la posición adecuada del primer o último elemento que coincide exactamente con su argumento.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();
Kennebec
fuente
1
Adición: IE admite forEach desde la versión 9, vea para cada método MSDN
rwitzel
75

Introducción

Desde mi tiempo en la universidad, he programado en Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL, C / C ++ y posiblemente en algunos otros idiomas que no puedo pensar en este momento.

Si bien todos tienen sus propias idiosincrasias lingüísticas, cada uno de estos idiomas comparte muchos de los mismos conceptos básicos. Dichos conceptos incluyen procedimientos / funciones, IF-declaraciones, FOR-loops y WHILE-loops.


Un forbucle tradicional

Un forbucle tradicional tiene tres componentes:

  1. La inicialización: ejecutada antes de que el bloque de búsqueda se ejecute por primera vez
  2. La condición: comprueba una condición cada vez antes de que se ejecute el bloque de bucle y abandona el bucle si es falso
  3. La idea de último momento: se realiza cada vez que se ejecuta el bloque de bucle

Estos tres componentes están separados entre sí por un ;símbolo. El contenido de cada uno de estos tres componentes es opcional, lo que significa que el siguiente es el forbucle más mínimo posible:

for (;;) {
    // Do stuff
}

Por supuesto, deberá incluir un if(condition === true) { break; } o un if(condition === true) { return; }lugar dentro de ese forbucle para que deje de funcionar.

Por lo general, sin embargo, la inicialización se usa para declarar un índice, la condición se usa para comparar ese índice con un valor mínimo o máximo, y la idea de último momento se usa para incrementar el índice:

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

Usar un forbucle tradicional para recorrer una matriz

La forma tradicional de recorrer una matriz es esta:

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

O, si prefiere hacer un bucle hacia atrás, haga esto:

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

Sin embargo, hay muchas variaciones posibles, como por ejemplo esta:

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

...o este...

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

...o este:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

Lo que funcione mejor depende en gran medida del gusto personal y del caso de uso específico que está implementando.

Tenga en cuenta que cada una de estas variaciones es compatible con todos los navegadores, incluidos los muy antiguos.


Un whilebucle

Una alternativa a un forbucle es un whilebucle. Para recorrer una matriz, puede hacer esto:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

Al igual que los forbucles tradicionales , los whilebucles son compatibles incluso con los navegadores más antiguos.

Además, tenga en cuenta que cada ciclo while se puede reescribir como un forciclo. Por ejemplo, el whilebucle anterior se comporta exactamente de la misma manera que este forbucle:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...in y for...of

En JavaScript, también puedes hacer esto:

for (i in myArray) {
    console.log(myArray[i]);
}

Sin embargo, esto debe usarse con cuidado, ya que no se comporta de la misma manera que un forciclo tradicional en todos los casos, y hay posibles efectos secundarios que deben considerarse. Consulte ¿Por qué usar "for ... in" con iteración de matriz es una mala idea? para más detalles.

Como alternativa a for...in, ahora también hay para for...of. El siguiente ejemplo muestra la diferencia entre un for...ofbucle y un for...inbucle:

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

Además, debe tener en cuenta que ninguna versión de Internet Explorer es compatible for...of( Edge 12+ lo hace) y que for...inrequiere al menos Internet Explorer 10.


Array.prototype.forEach()

Una alternativa a for-loops es Array.prototype.forEach(), que usa la siguiente sintaxis:

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach() es compatible con todos los navegadores modernos, así como con Internet Explorer 9 y versiones posteriores.


Bibliotecas

Finalmente, muchas bibliotecas de utilidad también tienen su propia foreachvariación. AFAIK, los tres más populares son estos:

jQuery.each(), en jQuery :

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each(), en Underscore.js :

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach(), en Lodash.js :

_.forEach(myArray, function(value, key) {
    console.log(value);
});
John Slegers
fuente
68

Usa el bucle while ...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

registros: 'uno', 'dos', 'tres'

Y para el orden inverso, un bucle aún más eficiente

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

registros: 'tres', 'dos', 'uno'

O el forbucle clásico

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

registros: 'uno', 'dos', 'tres'

Referencia: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/

Timo Huovinen
fuente
21
El primer ejemplo de la sintaxis "while" no funcionará si alguno de los elementos de la matriz es falso.
Chris Cooper
2
... y este ciclo while es equivalente a: for (var i = 0, item; item = items [i]; i ++), lo que elimina la necesidad de declarar las variables index y item de antemano ...
Stijn de Witt
39

Si desea una forma concisa de escribir un bucle rápido y puede iterar en reversa:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

Esto tiene el beneficio de almacenar en caché la longitud (similar for (var i=0, len=myArray.length; i<len; ++i)y diferente for (var i=0; i<myArray.length; ++i)) mientras que tiene menos caracteres para escribir.

Incluso hay algunas ocasiones en que debe iterar en reversa, como cuando itera sobre una NodeList en vivo donde planea eliminar elementos del DOM durante la iteración.

Phrogz
fuente
16
Para las personas que no entienden lo que es tan ingenioso: la expresión i-- se evalúa primero y permite que el ciclo continúe cuando no es falso ... Luego, el contador se decrementa. Tan pronto como me convierta en cero, saldrá del ciclo ya que cero es un valor falso en Javascript.
Stijn de Witt
55
falso? Te refieres a falsey.
Peguemos
44
He visto el término falso utilizar personas que considero gurús. Si es lo suficientemente bueno para ellos, es lo suficientemente bueno para mí. También me decepcionó ver que mi comentario que en realidad es atópico y agrega explicación / perspicacia obtiene 0 votos a favor, pero el comentario que señala un término en mi comentario obtiene 4. Ah, bueno, solo una cuestión de prioridades, supongo.
Stijn de Witt
"Almacenamiento en caché de la longitud"? La longitud se almacena como un entero en la matriz, no se mide cada vez que accede a ella. No hay ningún beneficio aquí al copiar el valor de la longitud en otra variable.
Mouscela
1
@ Varios Varios Estos días ciertamente no hay; en años anteriores, la iteración de matrices de JavaScript que almacenaban en caché la longitud en el lado de JavaScript (en lugar de llegar a través de la implementación) fue una clara ganancia de rendimiento (al microoptimizar). Por ejemplo, for (var i=0,len=array.length;i<len;++i)era un ciclo común y sensato para escribir.
Phrogz
36

Algunos usan casos de bucle a través de una matriz en la forma de programación funcional en JavaScript:

1. Solo recorre una matriz

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

Nota: Array.prototype.forEach () no es una manera funcional estrictamente hablando, ya que la función que toma como parámetro de entrada no debe devolver un valor, lo que no puede considerarse como una función pura.

2. Compruebe si alguno de los elementos de una matriz pasa una prueba

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. Transformar a una nueva matriz

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

Nota: El método map () crea una nueva matriz con los resultados de invocar una función proporcionada en cada elemento de la matriz que realiza la llamada.

4. Resume una propiedad particular y calcula su promedio

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. Cree una nueva matriz basada en el original pero sin modificarlo

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. Cuenta el número de cada categoría

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. Recupere un subconjunto de una matriz en función de criterios particulares

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

Nota: El método filter () crea una nueva matriz con todos los elementos que pasan la prueba implementada por la función proporcionada.

8. Ordenar una matriz

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

ingrese la descripción de la imagen aquí

9. Encuentra un elemento en una matriz

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

ingrese la descripción de la imagen aquí

El método Array.prototype.find () devuelve el valor del primer elemento de la matriz que satisface la función de prueba proporcionada.

Referencias

Yuci
fuente
30

Hay una manera de hacerlo donde tiene muy poco alcance implícito en su ciclo y elimina las variables adicionales.

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

O si realmente quieres obtener la identificación y tener un forbucle realmente clásico :

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

Los navegadores modernos métodos de apoyo todos los iteradores forEach, map, reduce, filtery una serie de otros métodos en el prototipo de matriz .

Gabriel
fuente
3
Tenga en cuenta que algunos intérpretes (por ejemplo, V8) almacenarán automáticamente en caché la longitud de la matriz si el código se llama suficientes veces y detecta que el ciclo no modifica la longitud.
Phrogz
Gracias por la información @Phrogz, es cierto que hay muchas optimizaciones que la VM puede hacer, pero dado que los navegadores más antiguos no tienen esto, sería una buena práctica optimizarlo ya que es muy barato.
Gabriel
1
@ Gabriel: ¿Por qué? Dé ejemplos del mundo real que demuestren que no almacenar en caché la longitud es en realidad un cuello de botella de rendimiento. Sigo el enfoque de "la optimización prematura es la raíz de todo mal". Arreglaré ese bucle que realmente plantea un problema una vez que lo encuentre ...
Stijn de Witt
1
@StijndeWitt imo es solo una cuestión estilística. Honestamente, ya ni siquiera lo uso para bucles, sino que me baso en el guión bajo para cosas como _.each, _.map, etc. para hacer estas cosas. Cuando escribí bucles como este, almacené en caché la longitud principalmente para que todas mis declaraciones de variables estuvieran en un lugar, en la parte superior de mi función. Seguir mi consejo a este respecto es intrascendente para cualquier aplicación del mundo real. La optimización prematura es súper mala, pero si la optimización resulta de decisiones estilísticas, no creo que realmente importe.
Gabriel
1
@Gabriel Creo que JavaScript ya admite la función de mapa en matrices, no es necesario introducir una lib adicional para eso.
Noz
28

Hay varias formas de recorrer la matriz en JavaScript.

Bucle genérico:

var i;
for (i = 0; i < substr.length; ++i) {
    // Do something with `substr[i]`
}

ES5 para cada uno:

substr.forEach(function(item) {
    // Do something with `item`
});

jQuery.each:

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

Mire esto para obtener información detallada o también puede verificar MDN para recorrer una matriz en JavaScript y usar jQuery, verifique jQuery para cada uno .

RizN81
fuente
27

Recomiendo encarecidamente hacer uso de la biblioteca underscore.js . Le proporciona varias funciones que puede usar para iterar sobre matrices / colecciones.

Por ejemplo:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
Andrew Thomson
fuente
77
Para los nuevos descubridores de esta pregunta, me gustaría señalar a Lo-Dash , un sucesor espiritual de Underscore que lo mejora de muchas maneras.
Mark Reed
3
¿Por qué usar underscoresi ECMA-262 ha agregado el forEachmétodo? El código nativo siempre es mejor.
Walter Chapilliquen - wZVanG
27

Bucle de matriz:

for(var i = 0; i < things.length; i++){
    var thing = things[i];
    console.log(thing);
}

Bucle de objeto:

for(var prop in obj){
    var propValue = obj[prop];
    console.log(propValue);
}
bzim
fuente
27

, puede hacer lo mismo en JavaScript usando un bucle, pero no se limita a eso, hay muchas formas de hacer un bucle sobre matrices en JavaScript. Imagine que tiene esta matriz a continuación, y le gustaría hacer un ciclo sobre ella:

var arr = [1, 2, 3, 4, 5];

Estas son las soluciones:

1) para bucle

Un forbucle es una forma común de recorrer matrices en JavaScript, pero no se considera la solución más rápida para matrices grandes:

for (var i=0, l=arr.length; i<l; i++) {
  console.log(arr[i]);
}

2) Mientras bucle

Un bucle while se considera la forma más rápida de recorrer bucles largos, pero generalmente se usa menos en el código JavaScript:

let i=0;

while (arr.length>i) {
    console.log(arr[i]);
    i++;
}

3) Haga mientras
A do whileestá haciendo lo mismo que whilecon alguna diferencia de sintaxis como se muestra a continuación:

let i=0;
do {
  console.log(arr[i]);
  i++;
}
while (arr.length>i);

Estas son las principales formas de hacer bucles de JavaScript, pero hay algunas formas más de hacerlo.

También usamos un for inbucle para recorrer objetos en JavaScript.

Busque también en los map(), filter(), reduce(), etc. funciones de un array en JavaScript. Pueden hacer las cosas mucho más rápido y mejor que usar whiley for.

Este es un buen artículo si desea obtener más información sobre las funciones asincrónicas sobre matrices en JavaScript.

La programación funcional ha tenido un gran impacto en el mundo del desarrollo en estos días. Y por una buena razón: las técnicas funcionales pueden ayudarlo a escribir más código declarativo que sea más fácil de entender de un vistazo, refactorizar y probar.

Una de las piedras angulares de la programación funcional es su uso especial de listas y operaciones de listas. Y esas cosas son exactamente como suenan: matrices de cosas y lo que les haces. Pero la mentalidad funcional los trata un poco diferente de lo que cabría esperar.

Este artículo analizará de cerca lo que me gusta llamar las operaciones de la lista de los "tres grandes": mapear, filtrar y reducir. Poner la cabeza en torno a estas tres funciones es un paso importante para poder escribir código funcional limpio, y abre las puertas a las poderosas técnicas de programación funcional y reactiva.

También significa que nunca más tendrás que escribir un bucle for.

Leer más >> aquí :

Alireza
fuente
¿Existe realmente una diferencia de rendimiento antes de un bucle for y un bucle while cuando se itera a través de una matriz? Tenía la impresión de que las diferencias eran principalmente sintácticas
Shea
24

Si alguien está interesado en el lado del rendimiento de los múltiples mecanismos disponibles para las iteraciones de matriz, he preparado las siguientes pruebas de JSPerf:

https://jsperf.com/fastest-array-iterator

Resultados de rendimiento

Resultados:

El for()iterador tradicional es, con mucho, el método más rápido, especialmente cuando se usa con la longitud de la matriz en caché .

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // Do something
}

El Array.prototype.forEach()y los Array.prototype.map()métodos son las aproximaciones más lentos, probablemente como consecuencia de la sobrecarga de llamada a la función .

colxi
fuente
es mejor uso en i = i +1lugar dei++
DarckBlezzer
2
Podría mejorarse: utilice: ++ i en lugar de i ++, esto evitará un objeto temporal. Por lo tanto, reduce el uso de memoria y el tiempo de CPU (no se requiere asignación).
PowerStat
@PowerStat, ¿puede proporcionar un enlace o referencia al respecto? Nunca he aheard de ello, suena interesante ...
colxi
1
@colxi Para cosas tan interesantes, deberías leer el material hardcore de C ++ de Herb Sutter y Scott Meyers. Lo de ++ i vs i ++ es del libro: C ++ excepcional: 47 acertijos de ingeniería, problemas de programación y soluciones. Creo que también se puede encontrar en gotw.ca pero se puede probar para cada lenguaje de programación.
PowerStat
21

Si está utilizando la biblioteca jQuery, considere usar http://api.jquery.com/jQuery.each/

De la documentación:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

Devoluciones: objeto

Descripción: una función iteradora genérica, que se puede utilizar para iterar sin problemas sobre objetos y matrices. Las matrices y los objetos en forma de matriz con una propiedad de longitud (como el objeto de argumentos de una función) se repiten por índice numérico, de 0 a longitud-1. Otros objetos se iteran a través de sus propiedades con nombre.

La $.each()función no es la misma que $(selector).each(), que se utiliza para iterar, exclusivamente, sobre un objeto jQuery. La $.each() función se puede usar para iterar sobre cualquier colección, ya sea un mapa (objeto JavaScript) o una matriz. En el caso de una matriz, la devolución de llamada se pasa un índice de matriz y un valor de matriz correspondiente cada vez. (También se puede acceder al valor a través de la thispalabra clave, pero Javascript siempre envolverá el thisvalor como Objectsi fuera una cadena simple o un valor numérico). El método devuelve su primer argumento, el objeto que fue iterado.

justingordon
fuente
99
jQuery para todo?
Excepción
66
De acuerdo con la excepción. No subestimes el impacto de las dependencias adicionales. Aconsejaría contra esto, excepto en el código que ya usa jQuery de todos modos.
Stijn de Witt
2
Actualización: en estos días, puede usar Array.forEach para obtener el mismo efecto con las matrices nativas.
Stijn de Witt
21

Todavía no vi esta variación, que personalmente me gusta más:

Dado un conjunto:

var someArray = ["some", "example", "array"];

Puede recorrerlo sin tener que acceder a la propiedad de longitud:

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

Vea este JsFiddle que demuestra que: http://jsfiddle.net/prvzk/

Esto solo funciona para matrices que no son dispersas. Lo que significa que en realidad hay un valor en cada índice de la matriz. Sin embargo, descubrí que en la práctica casi nunca uso matrices dispersas en JavaScript ... En tales casos, generalmente es mucho más fácil usar un objeto como un mapa / tabla hash. Si tiene una matriz dispersa y desea realizar un bucle sobre 0 .. longitud-1, necesita la construcción for (var i = 0; i <someArray.length; ++ i), pero aún necesita un ifdentro del bucle para verificar si el elemento en el índice actual está realmente definido.

Además, como CMS menciona en un comentario a continuación, solo puede usar esto en matrices que no contienen ningún valor falso. La matriz de cadenas del ejemplo funciona, pero si tiene cadenas vacías, o números que son 0 o NaN, etc., el bucle se interrumpirá prematuramente. Nuevamente, en la práctica, esto casi nunca es un problema para mí, pero es algo a tener en cuenta, lo que hace que sea un bucle en el que pensar antes de usarlo ... Eso puede descalificarlo para algunas personas :)

Lo que me gusta de este bucle es:

  • Es corto para escribir
  • No es necesario acceder (y mucho menos caché) a la propiedad de longitud
  • El elemento para acceder se define automáticamente dentro del cuerpo del bucle bajo el nombre que elija.
  • Se combina de forma muy natural con array.push y array.splice para usar matrices como listas / pilas

La razón por la que esto funciona es que la especificación de la matriz exige que cuando lea un elemento de un índice> = la longitud de la matriz, regrese indefinido. Cuando escribe en una ubicación de este tipo, se actualizará la longitud.

Para mí, esta construcción emula más estrechamente la sintaxis de Java 5 que me encanta:

for (String item : someArray) {
}

... con el beneficio adicional de conocer también el índice actual dentro del ciclo

Stijn de Witt
fuente
14
Tenga en cuenta que con este enfoque el bucle se detendrá tan pronto se encuentra un valor Falsey- , tales como una cadena vacía, 0, false, NaN, nullo undefined, incluso antes de que ialcance la longitud, por ejemplo: jsfiddle.net/prvzk/1
CMS
3
La condición del bucle podría ser (item=someArray[i]) !== undefined.
daniel1426
18

Hay un método para iterar solo sobre las propiedades del objeto propio, sin incluir las del prototipo:

for (var i in array) if (array.hasOwnProperty(i)) {
    // Do something with array[i]
}

pero aún iterará sobre propiedades definidas a medida.

En JavaScript, cualquier propiedad personalizada podría asignarse a cualquier objeto, incluida una matriz.

Si uno quiere iterar sobre una matriz dispersa, for (var i = 0; i < array.length; i++) if (i in array)o array.forEachcon es5shimdebe usarse.

kirilloid
fuente
¿Y qué tal el uso for (var i in array) if (++i)?
Daniel Sokolowski
15

Hay un par de formas de hacerlo en JavaScript. Los dos primeros ejemplos son ejemplos de JavaScript. El tercero hace uso de una biblioteca de JavaScript, es decir, jQuery hace uso de la .each()función.

var myStringArray = ["hello", "World"];
for(var i in myStringArray) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
for (var i=0; i < myStringArray.length; i++) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
$.each(myStringArray, function(index, value){
  alert(value);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Shubham Khatri
fuente
for...indebe evitarse para objetos tipo matriz
brk
15

La forma más elegante y rápida.

var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}

http://jsperf.com/native-loop-performance/8


Editado (porque estaba equivocado)


Comparar métodos para recorrer una matriz de 100000 elementos y hacer una operación mínima con el nuevo valor cada vez.

Preparación:

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

Pruebas:

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>
molokoloco
fuente
Este bucle no parece seguir el orden de los elementos en la matriz.
Deniz Ozger
Mi prueba estuvo mal. Es correcto, mostrando todos los LOOPS ahora. jsperf.com/native-loop-performance/16
molokoloco
@bergi tiene razón. Este bucle borra la matriz a medida que avanza por ella. No es lo que quieres en la mayoría de los casos.
Stijn de Witt
44
rompe en artículos falsey.
njzk2
12

El enfoque optimizado es almacenar en caché la longitud de la matriz y usar un patrón var único que inicialice todas las variables con una sola palabra clave var.

var i, max, myStringArray = ["Hello","World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
    alert(myStringArray[i]);
   //Do something
}

Si el orden de iteración no importa, debería intentar el bucle invertido, es más rápido ya que reduce las pruebas de condición de sobrecarga y la disminución está en una declaración:

var i,myStringArray = ["item1","item2"];
for (i =  myStringArray.length; i--) {
    alert(myStringArray[i]);
}

o mejor y más limpio para usar mientras bucle:

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}
Zaheer Ahmed
fuente
12

En JavaScript, hay muchas soluciones para recorrer una matriz.

Los siguientes códigos son populares

/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

for (let i = 0; i < items.length; i++) {
  console.log(items[i])
}

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()

Alongkorn Chetasumon
fuente
12

Si desea usar jQuery, tiene un buen ejemplo en su documentación:

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });
jj_
fuente
12

La mejor manera en mi opinión es usar la función Array.forEach. Si no puede usar eso, le sugiero que obtenga el polyfill de MDN. Para que esté disponible, sin duda es la forma más segura de iterar sobre una matriz en JavaScript.

Array.prototype.forEach ()

Como otros han sugerido, esto es casi siempre lo que quieres:

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

Esto garantiza que todo lo que necesite en el alcance del procesamiento de la matriz permanezca dentro de ese alcance, y que solo esté procesando los valores de la matriz, no las propiedades del objeto y otros miembros, que es lo que for ..hace.

El uso de un forbucle de estilo C normal funciona en la mayoría de los casos. Es importante recordar que todo lo que está dentro del ciclo comparte su alcance con el resto de su programa, el {} no crea un nuevo alcance.

Por lo tanto:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

for(var i = 0; i<numbers.length; ++i){
  sum += numbers[i];
}

alert(i);

generará "11", que puede o no ser lo que desea.

Un ejemplo de trabajo de jsFiddle: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/

Espen
fuente
10

No es 100% idéntico, pero similar:

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }

Muhammad Alvin
fuente
1
Parece que esto se enfrentaría a problemas similares a los de otros usos con un objeto de matriz, ya que las variables miembro prototipo también serían atrapadas por for in.
Kzqai
9

Por ejemplo, usé en una consola Firefox:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})
victorq10
fuente
9
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

Mucho más limpio ...

estático
fuente
Eso no es muy limpio en comparación con z.forEach(j => console.log(j));.
Sapphire_Brick
9

Respuesta corta: sí. Puedes hacer esto:

var myArray = ["element1", "element2", "element3", "element4"];

for (i = 0; i < myArray.length; i++) {
  console.log(myArray[i]);
}

En una consola del navegador, puede ver algo como "elemento1", "elemento2", etc., impreso.

Juanjo Salvador
fuente
9

Puedes usar Array.prototype.forEach(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.forEach((item, index)=>{
   //Some code...
});

O Array.prototype.map(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.map((item, index)=>{
   //Some code...
});

O el jquery o para las formas de bucle mencionadas anteriormente.

Zafiro_Brick
fuente