objeto - recorrer array javascript




Recorrer una matriz en JavaScript (20)

para (var s de myStringArray) {

(Respondiendo 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 realizar la iteración, el for..of loop.

Esta nueva sintaxis es la forma más elegante de iterar una matriz en javascript (siempre que no necesite el índice de iteración), pero los navegadores aún no la admiten ampliamente.

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

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 loops

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

}

En Java puede usar un bucle for 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?


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)

Comparando métodos para realizar un bucle a través de una matriz de 100000 elementos y realice 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>

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 en sentido estricto, ya que la función que toma como parámetro de entrada no debe devolver un valor, que por lo tanto 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 llamar a una función proporcionada en cada elemento de la matriz de llamada.

4. Resumir una propiedad particular, y calcular 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. Crea 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. Recuperar un subconjunto de una matriz basado en 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);

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

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

Referencias


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

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

También está optimizado ("caching" la longitud del arreglo). Si desea obtener más información, lea mi post sobre el tema .


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's forEach:

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 this para obtener información detallada o también puede verificar for...in para hacer un bucle a través de una matriz en JavaScript y usar jQuery check jQuery.each() .


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

Puede que no los necesite todos, pero pueden ser muy útiles, o lo sería si todos los navegadores los admitieran.

Mozilla Labs publicó los algoritmos que ambos y WebKit utilizan, para que puedas agregarlos tú mismo.

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

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

Algunas devoluciones son verdaderas si alguna 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 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;
})();

Recomiendo 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...

Sí, pero solo si su implementación incluye la función for ... of introducida en ECMAScript 2015 (la versión "Harmony").

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 a través de let y const :

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

Sin embargo, muchos desarrolladores de JavaScript todavía están trabajando en un entorno que aún no existe, especialmente si escriben código para ejecutar en navegadores web, donde los desarrolladores del sitio a menudo no pueden estar seguros de qué navegador / versión estarán usando sus clientes.

Si puede asumir que el intérprete de JavaScript cumple con la edición anterior de la especificación ECMAScript (que descarta, por ejemplo, las versiones de Internet Explorer antes de 9), puede usar el método de iterador forEach lugar de un bucle. En ese caso, usted pasa una función para ser llamada en cada elemento de la matriz:

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

Pero si incluso eso es demasiado para asumir, y quiere algo que funcione en todas las versiones de JavaScript, entonces tiene que usar un ciclo de conteo explícito. La versión más segura, que maneja adecuadamente los arreglos dispersos, es algo como esto:

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 expresión completa myStringArray.length en la condición de bucle) puede hacer una diferencia significativa en el rendimiento, ya que omite una búsqueda de propiedades cada vez; usando Rhino en mi máquina, la aceleración es del 43%.

A menudo verá el caché de longitud realizado en la cláusula de inicialización de bucle, como esto:

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

La sintaxis for ... in sintaxis mencionada por otros es para hacer un bucle sobre las propiedades de un objeto; dado que un Array en JavaScript es solo un objeto con nombres de propiedades numéricas (y una propiedad de length actualiza automáticamente), teóricamente puedes hacer un loop con un Array. Pero el problema es que no se restringe a los valores de las propiedades numéricas (recuerde que incluso los métodos son solo propiedades cuyo valor es un cierre), ni se itera sobre los en orden numérico. Por lo tanto, la sintaxis for ... in sintaxis no se debe usar para hacer un bucle a través de matrices.


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 lo clásico for loop.

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/


Utilice una secuencia for bucle:

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

@zipcodeman sugiere el uso de la instrucción for...in , pero para iterar matrices se debe evitar la entrada for-in , esa declaración está destinada a enumerar las propiedades del objeto.

No se debe utilizar para objetos de tipo matriz porque:

  • El orden de iteración no está garantizado, los índices de matriz pueden no visitarse 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 objeto Array.prototype 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) {
  alert(array[i]);
}

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

Esto puede ser particularmente un problema si utiliza alguna biblioteca que se basa en gran medida en el aumento de prototipos nativos (como MooTools, por ejemplo).

La instrucción for-in como dije antes está 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...
    alert("prop: " + prop + " value: " + obj[prop])
  }
}

En el ejemplo anterior, el método hasOwnProperty permite enumerar solo propiedades propias , eso es, solo las propiedades que el objeto tiene físicamente, no propiedades heredadas.

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


El enfoque optimizado es almacenar en caché la longitud de la matriz y usar un solo patrón de inicialización de todas las variables con una sola palabra clave de variable.

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 de lo que debería intentar con el bucle invertido, es más rápido ya que reduce la sobrecarga de pruebas 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 usar while loop:

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

En JavaScript, hay tantas soluciones para hacer un loop de 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()


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
    }


Por ejemplo, utilicé en una consola de Firefox:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})

Seguro que es ineficiente y muchos lo desprecian, pero es uno de los más cercanos a lo mencionado:

var myStringArray = ["Hello","World"];
myStringArray.forEach(function(f){
    // Do something
})

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:

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

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

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

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


Todavía no vi esta variación, que personalmente me gusta la mejor:

Dada una matriz:

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

Puede recorrerlo sin acceder nunca 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 que demuestra eso: 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 en la matriz. Sin embargo, encontré que en la práctica casi nunca uso arreglos dispersos en Javascript ... En tales casos, usualmente es mucho más fácil usar un objeto como un mapa / tabla hash. Si tiene una matriz dispersa y desea realizar un bucle en 0 .. longitud-1, necesita la construcción for (var i = 0; i <someArray.length; ++ i), pero aún necesita un if en el interior del bucle para comprobar si el elemento en el índice actual está realmente definido.

Además, como lo menciona CMS en un comentario a continuación, solo puede usar esto en arreglos que no contengan valores falsos. El conjunto 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. Una vez más, en la práctica, esto casi nunca es un problema para mí, pero es algo que se debe tener en cuenta, lo que hace que sea un bucle para 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 length
  • El elemento a acceder se define automáticamente dentro del cuerpo del bucle bajo el nombre que elija.
  • Combina de forma muy natural con array.push y array.splice para utilizar matrices como listas / pilas

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

Para mí, esta construcción emula más de cerca la sintaxis de Java 5 que amo:

for (String item : someArray) {
}

... con el beneficio adicional de saber también sobre el índice actual dentro del bucle


Hay un par de maneras 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>


Respuesta corta: si. Puedes hacer con 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 "element1", "element2", etc., impreso.


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 de iterador genérico, que se puede utilizar para iterar sin problemas en objetos y matrices. Las matrices y los objetos similares a una matriz con una propiedad de longitud (como el objeto de argumentos de una función) se iteran mediante un índice numérico, desde 0 hasta longitud-1. Otros objetos son iterados a través de sus propiedades nombradas.

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 utilizar 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 lo ajustará thiscomo un valor Objectpar si es una cadena simple o un valor numérico). El método devuelve su primer argumento, el objeto que se iteró.





for-loop