Recorrer una matriz en JavaScript

3540

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?

9
  • 5
    Ok, estoy un poco confundido, ¿está bien usar el bucle for mejorado cuando accedes a los objetos? ¿Y usar uno secuencial para llenar uno? ¿Es esto correcto? 10 de junio de 2010 a las 0:15
  • 49
    no, es realmente simple, los objetos de matriz tienen índices numéricos, por lo que desea iterar sobre esos índices en 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, siempre se recomiendan los bucles secuenciales ...for-in 10/06/10 a las 0:38
  • 4
    relacionado - stackoverflow.com/questions/5349425/… 1/11/11 a las 17:53
  • 7
    jsben.ch/#/Q9oD5 <= Aquí un punto de referencia de un montón de soluciones para recorrer arreglos 3 de nov. De 2016 a las 19:45
  • 6
    @CMS No, no es realmente simple. Es realmente simple en todos los demás idiomas. Es ridículamente complejo en JS, donde lo tiene iny ofpuede usarse y hacer cosas diferentes. Luego también tiene forEachy el feo y molesto bucle basado en índices. Todos los demás lenguajes modernos hacen que recorrer una colección sea fácil y directo sin sorpresas ni confusiones. JS también podría hacerlo, pero no es así.
    jpmc26
    5 oct 2018 a las 15:59
4484

Tres opciones principales:

  1. for (var i = 0; i < xs.length; i++) { console.log(xs[i]); }
  2. xs.forEach((x, i) => console.log(x));
  3. for (const x of xs) { console.log(x); }

A continuación se muestran ejemplos detallados.


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 entornos
  • Puede utilizar breaky continuecontrolar el flujo de declaraciones

Contras

  • Demasiado detallado
  • Imperativo
  • Fácil de tener errores uno por uno (a veces también llamado error de poste de cerca )

2 Array.prototype.forEach.:

La especificación ES5 introdujo muchos métodos de matriz beneficiosos. Uno de ellos, el Array.prototype.forEach, nos dio una forma concisa de iterar sobre una matriz:

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

Habiendo transcurrido casi diez años desde que se publicó la especificación ES5 (diciembre de 2009), ha sido implementada por casi todos los motores modernos en los entornos de escritorio, servidor y móvil, por lo que es seguro usarlos.

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

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

Las funciones de Arrow también se implementan ampliamente a menos que planee admitir plataformas antiguas (por ejemplo, Internet Explorer 11 ); también es seguro ir.

Pros

  • Muy breve y sucinto.
  • 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 anti-patrón tantas veces.

Anti-patrón:

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

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

Caso de uso adecuado 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 .

Anti-patró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 asincrónicos en serie.

Contras

No utilice for...in

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

No debe usarse para objetos similares a matrices porque:

  • El orden de iteración no está garantizado; es posible que los índices de la matriz no se visiten en orden numérico.
  • También se enumeran las propiedades heredadas.

El segundo punto es que le puede dar 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 hará que la consola registre "a", "b", "c" y "¡foo!".

Eso puede ser particularmente un problema si usa alguna biblioteca que se basa en gran medida en el aumento de prototipos nativos (como MooTools ).

La for-indeclaración, como dije antes, está ahí para enumerar las propiedades del objeto, 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 todo, solo las propiedades que el objeto tiene físicamente, no propiedades heredadas.

Te recomiendo que leas el siguiente artículo:

2
  • 1
    Sé que esta respuesta es anterior a async y Promises, pero creo que vale la pena mencionarlo en cualquier conversación relacionada con JavaScript moderno: " forEachno espera promesas. Asegúrese de conocer las implicaciones al usar promesas (o funciones asincrónicas) como forEachdevolución de llamada. " ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
    bmaupin
    15 de junio a las 11:41
  • con de es6 for-of: no se puede obtener el índice actual
    Vic
    9 de septiembre a las 1:13
1143
+50

Sí, asumiendo que su implementación incluye 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 las matrices dispersas: una matriz en JavaScript puede no almacenar tantos elementos como informa su length; ese número informado es simplemente uno mayor que el índice más alto en el que se almacena un valor. Si la matriz contiene menos elementos de 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; el lengthde una matriz de este tipo 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 desee "recorrer" una matriz, tiene una pregunta que responder: ¿desea recorrer el rango completo indicado por su longitud y proceso?undefineds para cualquier elemento faltante, o solo desea procesar los elementos realmente presentes? Hay muchas aplicaciones para ambos enfoques; solo depende de para qué estés usando la matriz.

Si itera sobre una matriz con for.. of, el cuerpo del bucle se ejecuta lengthveces y la variable de control de bucle se establece en undefinedpara cualquier elemento que no esté realmente presente en la matriz. Dependiendo de los detalles de su código "hacer algo con", ese comportamiento puede ser lo que desea, pero si no es así, 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.

Siempre que su implementación de JavaScript sea compatible 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 llame 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 los elementos que están realmente presentes en la matriz. Si 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 undefined; para el ú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 desde 0 hasta 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 .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 de bucle) puede marcar 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 la longitud realizado en la cláusula de inicialización del bucle, así:

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 le 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 el Array #entries método para cambiarlo a una matriz de [índice, elemento] pares, 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 un Array en JavaScript es solo un objeto con nombres de propiedad numéricos (y una lengthpropiedad actualizada automáticamente ), teóricamente puede recorrer un Array con él. Pero el problema es que no se limita a los valores numéricos de las propiedades (recuerde que incluso los métodos son en realidad solo propiedades cuyo valor es un cierre), ni se garantiza que se repita sobre ellos en orden numérico. Por lo tanto, la sintaxis for... no debe usarse para recorrer Arrays.in

1
  • 22
    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 bucle 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 su código se invoca suficientes veces para marcar la diferencia.
    Phrogz
    4/06/12 a las 16:29
446

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 propia matriz.

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 obtiene el new_list.

2
  • 100
    Ese ejemplo en particular probablemente se implemente mejor usando Array.forEach. mapes para generar una nueva matriz.
    harto
    10/06/10 a las 0:20
  • 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 ' Para sugerir la declaración for-in, consulte mi respuesta para obtener más detalles :) 10/06/10 a las 0:30
135

para (const s de myStringArray) {

(Respondiendo directamente a su pregunta: ¡ahora puede!)

La mayoría de las otras respuestas son correctas, pero no mencionan (al momento de escribir este artículo) que ECMAScript  6  2015 está trayendo un nuevo mecanismo para realizar iteraciones, el for..ofbucle.

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 de JavaScript (como Babel ) que nos permiten utilizar funciones de próxima generación en la actualidad.

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

Iterando una matriz

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

Iterando una matriz de objetos

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

for(const 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 (const 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 loops

Especificación: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}

0
121

En JavaScript no es aconsejable recorrer un Array con un bucle for-in, pero es mejor usar un forbucle como:

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

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

0
91

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

Puede 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 usted pueda agregarlos usted mismo.

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

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

some 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órelo hasta que lo necesite.

indexOf y lastIndexOf encuentran la posición apropiada 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;
})();
0
82

Introducción

Desde mi época en la universidad, he programado en Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL , C / C ++ y posiblemente algunos otros lenguajes en los 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, IFdeclaraciones, FORbucles y WHILEbucles.


Un forbucle tradicional

Un forbucle tradicional tiene tres componentes:

  1. La inicialización: se ejecuta antes de que el bloque de búsqueda se ejecute por primera vez.
  2. La condición: verifica una condición cada vez que se ejecuta el bloque de bucle y sale del bucle si es falso
  3. La ocurrencia tardía: 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 lo siguiente es el forbucle más mínimo posible:

for (;;) {
    // Do stuff
}

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

Sin embargo, por lo general, 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 ocurrencia tardía se usa para incrementar el índice:

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

Usando un forbucle tradicional para recorrer una matriz

La forma tradicional de recorrer una matriz es la siguiente:

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, existen 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 es en gran medida una cuestión de 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 puede hacer esto:

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

Sin embargo, esto debe usarse con cuidado, ya que no se comporta igual que un forbucle tradicional en todos los casos, y existen efectos secundarios potenciales que deben tenerse en cuenta. Consulte ¿Por qué utilizar "for ... in" para la iteración de matrices es una mala idea? para más detalles.

Como alternativa a for...in, ahora también existe 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 utilidades 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 :

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

Utilice el tiempo de bucle ...

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

Registra: 'uno', 'dos' y 'tres'

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

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

Registra: 'tres', 'dos' y '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]);
}

Registra: 'uno', 'dos', 'tres'

Referencia: Cierre de Google: cómo no escribir JavaScript

2
  • 21
    El primer ejemplo de la sintaxis "while" no funcionará si alguno de los elementos de la matriz es falso. 16/04/12 a las 14:42
  • 2
    ... y este bucle while es equivalente a: for (var i = 0, item; item = items [i]; i ++), lo que elimina la necesidad de declarar el índice y las variables del elemento de antemano ... 31/0313 a las 19:09
40

Si desea una forma concisa de escribir un bucle rápido y puede iterar al revés:

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

Esto tiene la ventaja 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)) a la vez que hay menos caracteres para escribir.

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

2
  • dieciséis
    Para las personas que no entienden lo que es tan ingenioso: Primero se evalúa la expresión i-- y permite que el bucle continúe cuando no es falso ... Luego se decrementa el contador. Tan pronto como me convierta en cero, saldrá del ciclo, ya que cero es un valor falso en Javascript. 1 de marzo de 2013 a las 12:09
  • 5
    falso? Te refieres a Falsey. Usemos la terminología adecuada para evitar confusiones;) 27/04/13 a las 7:33
38

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

1. Simplemente 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 forma funcional estrictamente hablando, ya que la función que toma como parámetro de entrada no debe devolver un valor, por lo que no puede considerarse 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 llamar a una función proporcionada en cada elemento de la matriz de llamada.

4. Resume una propiedad en 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 la original pero sin modificarla

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. Cuente 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 según 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

0
36

, puede hacer lo mismo en JavaScript usando un bucle, pero no limitado a eso. Hay muchas formas de hacer un bucle sobre matrices en JavaScript. Imagina que tienes esta matriz a continuación y te gustaría hacer un bucle 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 arreglos en JavaScript, pero no se considera la solución más rápida para arreglos grandes:

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

2) Mientras que el bucle

Un bucle while se considera la forma más rápida de recorrer matrices largas, 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 formas principales de realizar 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 usando whiley for.

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

Functional programming has been making quite a splash in the development world these days. And for good reason: Functional techniques can help you write more declarative code that is easier to understand at a glance, refactor, and test.

One of the cornerstones of functional programming is its special use of lists and list operations. And those things are exactly what the sound like they are: arrays of things, and the stuff you do to them. But the functional mindset treats them a bit differently than you might expect.

This article will take a close look at what I like to call the "big three" list operations: map, filter, and reduce. Wrapping your head around these three functions is an important step towards being able to write clean functional code, and opens the doors to the vastly powerful techniques of functional and reactive programming.

It also means you'll never have to write a for loop again.

Leer más >> aquí :

0
30

Hay una forma de hacerlo en la que 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 desea 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 .

6
  • 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
    4/06/12 a las 16:28
  • Gracias por la información @Phrogz, es cierto que hay muchas optimizaciones que la máquina virtual 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
    26/06/12 a las 1:43
  • 1
    @Gabriel: ¿Por qué? Proporcione ejemplos del mundo real que muestren que no almacenar en caché la longitud es en realidad un cuello de botella en el rendimiento. Sigo el enfoque de "la optimización prematura es la raíz de todos los males". Arreglaré ese bucle que realmente plantea un problema una vez que lo encuentre ... 31/0313 a las 19:06
  • 1
    @StijndeWitt imo, es solo una cuestión de estilo. Honestamente, ya ni siquiera uso bucles for, sino que confío en el subrayado para cosas como _.each, _.map, etc. para hacer estas cosas. Cuando escribí bucles como este, guardé la longitud en caché principalmente para que toda mi declaración de variable estuviera en un solo 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 muy mala, pero si la optimización resulta de decisiones estilísticas, no creo que realmente importe.
    Gabriel
    4 abr 13 a las 17:15
  • 1
    @Gabriel Creo que JavaScript ya es compatible con la función de mapa en matrices, no es necesario introducir una biblioteca adicional para eso.
    Noz
    30/07/2014 a las 18:14
29

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

Eche un vistazo a esto para obtener información detallada o también puede verificar MDN para recorrer una matriz en JavaScript y usar jQuery verificar jQuery para cada uno .

0
29

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

Recomendaría encarecidamente hacer uso de la biblioteca Underscore.js . Le proporciona varias funciones que puede utilizar para iterar sobre matrices / colecciones.

Por ejemplo:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
2
  • 7
    Para los nuevos descubridores de esta pregunta, solo me gustaría señalar a Lo-Dash , un sucesor espiritual de Underscore que lo mejora de muchas maneras. 11/10/2013 a las 10:59
  • 3
    ¿Por qué usarlo underscoresi se ha agregado ECMA-262 al forEachmétodo. El código nativo siempre es mejor. 23/06/15 a las 23:32
24

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

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

Resultados de desempeño

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 .

4
  • es mejor usar en i = i +1lugar dei++ 10/12/18 a las 18:19
  • 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 la CPU (no se requiere asignación)! 17 de mayo de 2019 a las 10:05
  • @PowerStat, ¿puede proporcionar un enlace o una referencia al respecto? Nunca he oído hablar de eso, suena interesante ...
    colxi
    17 de mayo de 2019 a las 13:23
  • 1
    @colxi Para cosas tan interesantes, debería leer el material 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 puede encontrarlo en gotw.ca, pero se puede probar para todos los lenguajes de programación. 17 de mayo de 2019 a las 17:44
21

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

De la documentación:

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

Returns: Object

Description: A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.

The $.each() function is not the same as $(selector).each(), which is used to iterate, exclusively, over a jQuery object. The $.each() function can be used to iterate over any collection, whether it is a map (JavaScript object) or an array. In the case of an array, the callback is passed an array index and a corresponding array value each time. (The value can also be accessed through the this keyword, but Javascript will always wrap the this value as an Object even if it is a simple string or number value.) The method returns its first argument, the object that was iterated.

2
  • 6
    De acuerdo con excepción. No subestime el impacto de las dependencias adicionales. Aconsejaría en contra de esto, excepto en el código que ya está usando jQuery en gran medida de todos modos. 31/0313 a las 19:04
  • 2
    Actualización: en estos días, puede usar Array.forEach para obtener gran parte del mismo efecto con matrices nativas. 5 de junio de 2017 a las 10:50
21

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

Dada una matriz:

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

Puede recorrerlo sin tener que acceder a la propiedad length:

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 demostrando que: http://jsfiddle.net/prvzk/

Esto solo funciona para matrices que no son escasas. 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 mapa / tabla hash. Si tiene una matriz dispersa y desea recorrer 0 .. length-1, necesita la construcción for (var i = 0; i <someArray.length; ++ i), pero aún necesita una ifdentro del bucle para comprobar 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 valores falsos. 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 este sea un ciclo 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 almacenar en caché) la propiedad de longitud
  • El elemento al que acceder se define automáticamente dentro del cuerpo del bucle con 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, devolverá undefined. Cuando escribe en una ubicación de este tipo, en realidad actualizará la longitud.

Para mí, esta construcción emula más de cerca 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 bucle

2
  • 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 28 feb 2013 a las 18:31
  • 3
    La condición del bucle podría ser (item=someArray[i]) !== undefined. 20/0314 a las 14:17
19

Camino esotérico mutable

let a= ["Hello", "World"];

while(a.length) { console.log( a.shift() ); }
10
  • esa es la forma Haskell-y de hacerlo; sigue tomando el primero. inteligente, pero probablemente lento. 16 de enero de 2020 a las 2:49
  • @Sapphire_Brick en realidad es bastante rápido, aquí está la prueba 24 jul.20 a las 10:06
  • 4
    Tienes un buen punto. Ejecuté su ejemplo con una matriz de 1000 elementos y while(a.length) { console.log(a.shift()); }fue aproximadamente el doble de rápido que la for(var i = 0; i < a.length; i++) { console.log(a[i]); }versión. ¯ \ _ (ツ) _ / ¯ 4 ago.20 a las 20:51
  • 3
    Incluso si no existe en su idioma nativo, no debe omitir artículos en inglés (el artículo indefinido ("a" o "an") y el artículo definido ("el")). Consulte, por ejemplo, artículos en inglés: 3 reglas simples para corregir errores y errores gramaticales comunes y A, AN, THE: artículos en inglés . 30 oct.20 a las 8:35
  • 2
    @Pitouli, tienes razón: retrocedo la respuesta a su forma inicial. Cuando tenga más tiempo, volveré a realizar puntos de referencia. 1 de marzo a las 5:21
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 seguirá iterando sobre las propiedades definidas de forma personalizada.

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

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

1
  • ¿Y qué tal usar for (var i in array) if (++i)? 9/10/2014 a las 14:40
16

Hay 4 formas de iteración de matrices:

// 1: for

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

// 2: forEach

arr.forEach((v, i) => console.log(v));

// 3: for in

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

// 4: for of

for (const v of arr) {
  console.log(v);
}

Resumen : las soluciones 1 y 3 crean una variable adicional, 2: crean un contexto de función adicional. La mejor forma es la cuarta - "para de" .

2
  • 1
    ¿Te importaría explicar por qué 4 "para de" es el mejor sobre los demás? 3 de agosto a las 2:04
  • No crea variables innecesarias o contexto de función. Pero si no te importan las pequeñas desventajas puedes utilizar cualquiera de ellas, lo que te resulte más cómodo. @YesItsMe Gracias por la pregunta. 3 de agosto a las 9:39
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 me equivoqué)


Comparar métodos para recorrer una matriz de 100000 elementos y realizar 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>
4
  • Este bucle no parece seguir el orden de los elementos de la matriz. 26 mar '14 a las 15:36
  • Mi prueba fue incorrecta. Es correcto, ahora se muestran todos los LOOPS. jsperf.com/native-loop-performance/16 27 de marzo de 2014 a las 16:41
  • @bergi tiene razón. Este bucle borra la matriz a medida que la recorre. No es lo que quieres en la mayoría de los casos. 15 de mayo de 2014 a las 17:34
  • 4
    roturas en artículos falsos.
    njzk2
    29/07/14 a las 14:59
14

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>
1
  • for...in debe evitarse para objetos tipo Array
    brk
    5 de diciembre de 2016 a las 5:25
13

6 métodos diferentes para recorrer la matriz

Puede recorrer una matriz mediante muchos métodos diferentes. He ordenado mis 6 métodos favoritos de arriba a abajo.

1. Uso de bucle for

Cuando se trata simplemente de recorrer una matriz, el forbucle es mi primera opción.

let array = [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
  console.log(array[i]);
}

2. Usando forEach loop

forEachloop es una forma moderna de recorrer la matriz. Además, brinda más flexibilidad y control sobre la matriz y los elementos.

let array = [1, 2, 3, 4, 5];
array.forEach((element) => {
  console.log(element);
});

3. Utilizando para ... de

for...of loop le da acceso directo a los elementos de la matriz.

let array = [1, 2, 3, 4, 5];
for (let element of array) {
  console.log(element);
}

4. Utilizando for ... in loop

for...in le da una clave con la que puede acceder a los elementos de la matriz.

let array = [1, 2, 3, 4, 5];
for(let index in array){
  console.log(array[index]);
}

5. Uso del bucle while

while loop is también se puede usar para recorrer la matriz.

let array = [1, 2, 3, 4, 5];
let length = array.length;
while(length > 0){
  console.log(array[array.length - length]);
  length--;
}

6. Usando do ... while loop

Del mismo modo, uso do...whileloop

let array = [1, 2, 3, 4, 5];
let length = array.length;
do {
  console.log(array[array.length - length]);
  length--;
}
while (length > 0)
12

En JavaScript, hay muchas soluciones para hacer un bucle en 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()
12

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

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

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

Array.prototype.forEach ()

Entonces, como han sugerido otros, esto es casi siempre lo que desea:

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

Esto asegura 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 dentro del ciclo comparte su alcance con el resto de su programa, el {} no crea un nuevo alcance.

Por eso:

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 ser o no lo que desea.

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

12

El enfoque optimizado es almacenar en caché la longitud de la matriz y usar el patrón de variable única, inicializando todas las variables con una sola varpalabra clave.

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, entonces debería intentar el ciclo inverso. Es el más rápido, ya que reduce las pruebas de condiciones generales y la disminución se encuentra en una declaración:

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

O mejor y más limpio para utilizar un tiempo de bucle:

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // Do something with fruits[i]
}
11

No es 100% idéntico, pero similar:

   var myStringArray = ['Hello', 'World']; // The array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }
1
  • 1
    Parece que esto se enfrentaría a problemas similares a otros usos de for in con un objeto de matriz, en el sentido de que las variables de miembro prototipo también serían capturadas por for in.
    Kzqai
    18/04/12 a las 15:34
10

La forma formal (y quizás antigua) es Array.prototype.forEach(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.forEach(function(item, index, _) {
   console.log("[" + index + "] = '" + item + "'");
});
1
  • su "código" debería haber tenido un ejemplo. No está del todo claro si las variables se pasan directamente o como "esto" o lo que sea. 23/10/20 a las 16:17