Passa attraverso un array in JavaScript


3147

In Java è possibile utilizzare un forciclo per attraversare oggetti in un array come segue:

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

Puoi fare lo stesso in JavaScript?


5
Ok, quindi sono un po 'confuso, va bene usare il ciclo avanzato for quando si accede agli oggetti? E usare uno sequenziale per riempire uno? È corretto?
Mark Szymanski il

45
no, è davvero semplice, gli oggetti array hanno indici numerici, quindi vuoi iterare su quegli indici in ordine numerico, un ciclo sequenziale assicura che, il ciclo avanzato enumera le proprietà degli oggetti, senza un ordine specifico, ed enumera anche le proprietà ereditate. .. per iterare su matrici si consigliano sempre cicli sequenziali ...for-in
CMS


6
jsben.ch/#/Q9oD5 <= Qui un punto di riferimento di una serie di soluzioni per il looping di array
EscapeNetscape

3
@CMS No, non è molto semplice. È davvero semplice in ogni altra lingua. È ridicolmente complesso in JS, dove hai ine ofche può essere usato e fare cose diverse. Quindi hai anche forEachil brutto e fastidioso loop basato sull'indice. Ogni altro linguaggio moderno rende il ciclo di una raccolta facile e diretto senza sorprese o confusione. Anche JS potrebbe, ma non lo è.
jpmc26,

Risposte:


3965

Hai diverse opzioni:

1. forAnello sequenziale :

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

Professionisti

  • Funziona su ogni ambiente
  • È possibile utilizzare breake continuecontrollare le istruzioni di controllo

Contro

  • Troppo prolisso
  • Imperativo
  • Facile avere errori off-by-one (a volte anche chiamati errori post di recinzione )

2. Array.prototype.forEach

La specifica ES5 ha introdotto molti metodi di array utili, uno di questi, Array.prototype.forEache ci offre un modo conciso di iterare su un array:

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

Essendo quasi dieci anni come il momento in cui è stata rilasciata la specifica ES5 (dicembre 2009), è stata implementata da quasi tutti i motori moderni negli ambienti desktop, server e mobile, quindi è sicuro utilizzarli.

E con la sintassi della funzione freccia ES6, è ancora più conciso:

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

Le funzioni Arrow sono anche ampiamente implementate a meno che non si preveda di supportare piattaforme antiche (ad es. IE11); sei anche sicuro di andare.

Professionisti

  • Molto corto e succinto.
  • Dichiarativo

Contro

  • Impossibile utilizzare break/continue

Normalmente, è possibile sostituire la necessità di breakescludere i loop imperativi filtrando gli elementi dell'array prima di iterarli, ad esempio:

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

Tieni presente che se stai iterando un array per creare un altro array da esso , dovresti usare map, ho visto questo anti-pattern così tante volte.

Anti-modello:

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

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

Caso d'uso corretto della mappa :

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

console.log(doubled);

Inoltre, se si sta tentando di ridurre la matrice a un valore, ad esempio, si desidera sommare una matrice di numeri, è necessario utilizzare il metodo di riduzione .

Anti-modello:

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

L'uso corretto di ridurre :

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

console.log(sum);

3. for-ofDichiarazione ES6

Lo standard ES6 introduce il concetto di oggetti iterabili e definisce un nuovo costrutto per attraversare i dati, la for...ofdichiarazione.

Questa affermazione funziona per qualsiasi tipo di oggetto iterabile e anche per i generatori (qualsiasi oggetto che ha una [Symbol.iterator]proprietà).

Gli oggetti array sono per definizione iterabili integrati in ES6, quindi è possibile utilizzare questa istruzione su di essi:

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

Professionisti

  • Può iterare su una grande varietà di oggetti.
  • Può usare le normali istruzioni di controllo del flusso ( break/ continue).
  • Utile per iterare valori asincroni in serie.

Contro

Non usare for...in

@zipcodeman suggerisce l'uso dell'istruzione for...in, ma per iterare le matrici for-indovrebbe essere evitata, quell'istruzione ha lo scopo di enumerare le proprietà degli oggetti.

Non dovrebbe essere usato per oggetti simili a array perché:

  • L'ordine di iterazione non è garantito; gli indici di array non possono essere visitati in ordine numerico.
  • Le proprietà ereditate sono anche elencate.

Il secondo punto è che può darti molti problemi, ad esempio se estendi l' Array.prototypeoggetto per includere un metodo lì, anche quella proprietà verrà enumerata.

Per esempio:

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

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

Il codice sopra conserverà il registro "a", "b", "c" e "pippo!".

Ciò è particolarmente un problema se si utilizza una libreria che si basa fortemente sull'aumento dei prototipi nativi (come ad esempio MooTools).

L' for-inaffermazione come ho detto prima è lì per enumerare le proprietà degli oggetti, ad esempio:

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

Nell'esempio sopra, il hasOwnPropertymetodo ti consente di enumerare solo le proprietà proprie , tutto qui, solo le proprietà che l'oggetto ha fisicamente, nessuna proprietà ereditata.

Ti consiglierei di leggere il seguente articolo:


21
Questo è il motivo (da parte del CMS stesso) stackoverflow.com/questions/1885317/…
OscarRyz

15
@DoubleGras, penso che sia un'opinione che non è condivisa da tutti. Vedi: stackoverflow.com/questions/5752906/… o groups.google.com/forum/?fromgroups#!topic/jsmentors/…
Matthijs Wessels

3
Chiunque pensi di dover memorizzare nella cache la lunghezza ... Vedi la mia risposta, non è nemmeno necessario accedervi una sola volta, figuriamoci memorizzarlo nella cache: for (var i = 0, item; item = myStringArray [i]; i ++) {/ * usa l'oggetto qui * /}
Stijn de Witt,

15
@StijndeWitt No, perché che le interruzioni se avete dei "Falsey" valori nella propria matrice: false, undefined, 0, "", NaN.
Phrogz,

6
jsperf.com/caching-array-length/4 Ecco un test per vedere se vale la pena memorizzare nella cache la lunghezza di un array in un ciclo Javascript
Enrico

1116

Sì, supponendo che la tua implementazione includa la funzione for...of introdotta in ECMAScript 2015 (la versione "Harmony") ... che è un presupposto abbastanza sicuro in questi giorni.

Funziona così:

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

O meglio ancora, dal momento che ECMAScript 2015 fornisce anche variabili con ambito di blocco:

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

(La variabile sè diversa su ogni iterazione, ma può comunque essere dichiarata constall'interno del corpo del loop purché non sia modificata lì.)

Una nota sugli array sparsi: un array in JavaScript potrebbe non archiviare tutti gli elementi riportati dai suoi length; quel numero riportato è semplicemente uno maggiore dell'indice più alto in cui è memorizzato un valore. Se l'array contiene meno elementi di quanto indicato dalla sua lunghezza, si dice che sia scarso . Ad esempio, è perfettamente legittimo disporre di un array con elementi solo negli indici 3, 12 e 247; il valore lengthdi un tale array è riportato come 248, sebbene in realtà stia memorizzando solo 3 valori. Se si tenta di accedere a un elemento in qualsiasi altro indice, la matrice sembrerà avere il undefinedvalore lì. Pertanto, quando si desidera "passare in rassegna" un array, è necessario rispondere a una domanda: si desidera eseguire il ciclo su tutto l'intervallo indicato dalla sua lunghezza e processoundefineds per eventuali elementi mancanti o vuoi solo elaborare gli elementi effettivamente presenti? Esistono molte applicazioni per entrambi gli approcci; dipende solo da cosa stai usando l'array.

Se si esegue l'iterazione su un array con for.. of, il corpo del ciclo viene eseguito lengthvolte e la variabile di controllo del ciclo viene impostata su undefinedper tutti gli elementi non presenti nell'array. A seconda dei dettagli del codice "fai qualcosa con", quel comportamento potrebbe essere quello che vuoi, ma in caso contrario, dovresti usare un approccio diverso.

Naturalmente, alcuni sviluppatori hanno altra scelta che utilizzare un approccio diverso in ogni caso, perché per qualsiasi motivo che stanno destinati a una versione di JavaScript che non supporta ancora for... of.

Finché l'implementazione JavaScript è conforme alla precedente edizione della specifica ECMAScript (che esclude, ad esempio, le versioni di Internet Explorer precedenti alla 9), è possibile utilizzare il Array#forEachmetodo iteratore anziché un ciclo. In tal caso, si passa una funzione da chiamare su ciascun elemento dell'array:

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

A differenza di for... of, .forEachchiama la funzione solo per gli elementi che sono effettivamente presenti nell'array. Se viene passato il nostro ipotetico array con tre elementi e una lunghezza di 248, chiamerà la funzione solo tre volte, non 248 volte. Distingue anche tra elementi mancanti ed elementi che sono effettivamente impostati undefined; per quest'ultimo, chiamerà comunque la funzione, passando undefinedcome argomento. Se questo è il modo si desidera gestire le matrici sparse, .forEachpuò essere la strada da percorrere anche se i supporti interprete for... of.

L'ultima opzione, che funziona in tutte le versioni di JavaScript, è un ciclo di conteggio esplicito . Basta contare da 0 a uno in meno della lunghezza e utilizzare il contatore come indice. Il ciclo di base è simile al seguente:

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

Un vantaggio di questo approccio è che puoi scegliere come gestire le matrici sparse; il codice di cui sopra verrà eseguito il corpo del ciclo delle piene lengthtempi, con sset di undefinedeventuali elementi mancanti, proprio come for.. of. Se invece vuoi gestire solo gli elementi attualmente presenti di una matrice sparsa, come .forEach, puoi aggiungere un semplice intest sull'indice:

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

Assegnare il valore di lunghezza alla variabile locale (anziché includere l' myStringArray.lengthespressione completa nella condizione del ciclo) può fare una differenza significativa nelle prestazioni poiché salta ogni volta una ricerca di proprietà; usando Rhino sulla mia macchina, l'accelerazione è del 43%.

È possibile visualizzare la memorizzazione nella cache della lunghezza nella clausola di inizializzazione del ciclo, in questo modo:

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

Il ciclo di conteggio esplicito significa anche che hai accesso all'indice di ciascun valore, se lo desideri. L'indice viene inoltre passato come parametro aggiuntivo alla funzione a cui si passa forEach, quindi è possibile accedervi anche in questo modo:

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

for... ofnon ti dà l'indice associato a ciascun oggetto, ma finché l'oggetto su cui stai iterando è effettivamente un Array( for.. offunziona per altri tipi iterabili che potrebbero non avere questo metodo), puoi usare l' Array Metodo #entries per cambiarlo in un array di coppie [index, item], e quindi scorrere su quello:

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

La sintassi for... inmenzionata da altri è per il looping sulle proprietà di un oggetto; poiché un array in JavaScript è solo un oggetto con nomi di proprietà numerici (e una lengthproprietà aggiornata automaticamente ), è possibile teoricamente eseguire il loop su un array con esso. Ma il problema è che non si limita ai valori delle proprietà numeriche (ricorda che anche i metodi sono in realtà solo proprietà il cui valore è una chiusura), né è garantito che iterino su quelli in ordine numerico. Pertanto, la sintassi for... nonin deve essere utilizzata per il looping degli array.


21
Si noti che alcuni interpreti (ad es. V8) memorizzeranno automaticamente in cache la lunghezza dell'array se il codice viene chiamato abbastanza volte e rileva che la lunghezza non viene modificata dal loop. Mentre la memorizzazione nella cache della lunghezza è ancora buona, potrebbe non fornire un aumento di velocità quando il codice viene invocato abbastanza volte da fare davvero la differenza.
Phrogz,

2
@ mark-reed Potresti spiegare perché hai usato i in myStringArraynel tuo esempio? Come può essere falso?
Denis V,

2
@DenisV: false. a=[1,2,3,4]; delete a[2]; for (j in a) { console.log(j); } le uscite 0, 1, 3 e 4. a.lengthsono ancora 5.
Mark Reed,

1
Non sto suggerendo for j in a. Sto dimostrando che il incontrollo non è ridondante, come hai affermato, mostrando tutti gli indici e mostrando che ce n'è uno tra 0 e length-1che non c'è. Avrei potuto anche solo stampare 2 in a, il che è davvero false, nonostante il fatto che tu abbia detto che era impossibile.
Mark Reed,

2
@GrijeshChauhan - corretto. Ad esempio, IE fino alla versione 8 non lo supporta. Vedere questa domanda .
Mark Reed,

442

È possibile utilizzare map, che è una tecnica di programmazione funzionale che è disponibile anche in altre lingue come Python e Haskell .

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

La sintassi generale è:

array.map(func)

In generale func, prenderebbe un parametro, che è un elemento dell'array. Ma nel caso di JavaScript, può richiedere un secondo parametro che è l'indice dell'elemento e un terzo parametro che è l'array stesso.

Il valore restituito di array.mapè un altro array, quindi puoi usarlo in questo modo:

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

E ora x lo è [10,20,30,40].

Non è necessario scrivere la funzione in linea. Potrebbe essere una funzione separata.

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

new_list = my_list.map(item_processor);

che sarebbe in qualche modo equivalente a:

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

Solo che non hai capito new_list.


7
No, ma può essere più potente. check this out: joelonsoftware.com/items/2006/08/01.html
hasen

97
Questo esempio particolare è probabilmente meglio implementato usando Array.forEach. mapserve per generare un nuovo array.
harto

21
@hasen, il Array.prototype.mapmetodo fa parte dell'ECMAScript 5th Edition Standard, non è ancora disponibile su tutte le implementazioni (ad es. IE ne manca), anche per iterare su un array penso che il Array.prototype.forEachmetodo sia più semanticamente corretto ... t suggerisco la dichiarazione for-in, vedi la mia risposta per maggiori dettagli :)
CMS

3
La differenza tra forEache mapè che il primo non restituisce i risultati dell'iterazione. map(a volte aka collect, ma molto diverso da apply) è espressamente per trasformare ogni elemento di un array in un risultato corrispondente; è una mappatura da 1 a 1 , da cui il nome. Fa parte di un'intera famiglia di operazioni che include reduce(che produce un singolo risultato dall'intero array) e filter(che produce un sottoinsieme dell'array originale) e così via. Mentre forEachfa semplicemente qualcosa con ogni elemento, la semantica non è specificata.
Mark Reed,

4
Un downvote perché se in realtà non stai mappando qualcosa, usare [] .map è fuorviante. [] .forOach ha senso semantico e passa anche gli stessi tre argomenti alla funzione.
gengkev,

120

In JavaScript non è consigliabile eseguire il loop in un array con un ciclo for-in, ma è meglio utilizzare un forloop come:

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

Inoltre è ottimizzato ("memorizzazione nella cache" della lunghezza dell'array). Se vuoi saperne di più, leggi il mio post sull'argomento .


2
myArray.forEach (function (obj) {}); è ancora il migliore
Jan Sverre,

un piccolo miglioramento: potresti usare ++iinvece dii++
roberkules il

14
++iè una vecchia scuola che di ottimizzazione dei compilatori moderni fanno per voi in un ciclo da molto tempo fa :) stackoverflow.com/a/1547433/1033348
ngryman

6
Devi stare attento usando questo ciclo. Ho iniziato a usarlo e ho avuto un bug difficile da rintracciare a causa di un errore che ho fatto. Se annidate due loop in questo modo: jsfiddle.net/KQwmL/1 . Devi stare attento a nominare la var in modo diverso nei due loop, altrimenti il ​​secondo loop sovrascriverà la prima.
Rui Marques,

1
Rui Marques - puoi nominare la tua variabile i_stopo i_endinvece di len. È altrettanto leggibile (se non di più!) E eviterai naturalmente questo tipo di problema (dal momento che l'altro ciclo avrà, ad esempio, j_stop).
Chip Hogg,

119

for (let s di myStringArray) {

(Rispondi direttamente alla tua domanda: ora puoi!)

La maggior parte delle altre risposte sono giuste, ma non menzionano (al momento della stesura di questo documento) che ECMA Script  6  2015 sta introducendo un nuovo meccanismo per eseguire l'iterazione, il for..ofciclo.

Questa nuova sintassi è il modo più elegante per iterare un array in javascript (purché non sia necessario l'indice di iterazione).

Attualmente funziona con Firefox 13+, Chrome 37+ e non funziona in modo nativo con altri browser (vedere la compatibilità del browser di seguito). Fortunatamente abbiamo compilatori JS (come Babel ) che ci consentono di utilizzare le funzionalità di prossima generazione oggi.

Funziona anche su Node (l'ho testato sulla versione 0.12.0).

Iterazione di un array

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

Iterazione di una matrice di oggetti

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

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

Iterazione di un generatore:

(esempio estratto da 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;
  }
}

Tabella di compatibilità: http://kangax.github.io/es5-compat-table/es6/#For..of loop

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

}


Se stai usando ES6, suggerirei const sinvece divar s
joeytwiddle,

Nei miei test su array di grandi dimensioni, l'utilizzo var s of arrè quasi il doppio (1,9x) del tempo di esecuzione rispetto all'utilizzo di un semplice contatore per-loop e al recupero di elementi per indice in nodejs
theferrit32

Perché quella strana roba nella prima e nell'ultima riga?
Peter Mortensen,

91

Opera, Safari, Firefox e Chrome ora condividono tutti una serie di metodi Array avanzati per ottimizzare molti loop comuni.

Potresti non averne bisogno tutti, ma possono essere molto utili, o lo sarebbero se tutti i browser li supportassero.

Mozilla Labs ha pubblicato gli algoritmi utilizzati da entrambi e WebKit , in modo da poterli aggiungere da soli.

Il filtro restituisce una matrice di elementi che soddisfano alcune condizioni o test.

tutto restituisce vero se ogni membro dell'array supera il test.

alcuni restituiscono true se qualcuno supera il test.

forEach esegue una funzione su ciascun membro dell'array e non restituisce nulla.

map è come forOach, ma restituisce una matrice dei risultati dell'operazione per ciascun elemento.

Tutti questi metodi accettano una funzione per il loro primo argomento e hanno un secondo argomento opzionale, che è un oggetto il cui ambito si desidera imporre ai membri dell'array mentre eseguono il ciclo attraverso la funzione.

Ignoralo fino a quando non ti serve.

indexOf e lastIndexOf trovare la posizione appropriata del primo o l'ultimo elemento che corrisponde esattamente il suo argomento.

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

1
Aggiunta: IE supporta forOach dalla versione 9, vedi per ogni metodo MSDN
rwitzel

75

Intro

Fin dal mio periodo al college, ho programmato in Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL, C / C ++ e forse alcune altre lingue che non riesco a pensare in questo momento.

Mentre tutti hanno le loro idiosincrasie linguistiche, ognuna di queste lingue condivide molti degli stessi concetti di base. Tali concetti includono procedure / funzioni, IFdichiarazioni, FORloop e WHILEloop.


Un forcerchio tradizionale

Un forloop tradizionale ha tre componenti:

  1. L'inizializzazione: eseguita prima che il blocco visivo venga eseguito per la prima volta
  2. La condizione: controlla una condizione ogni volta prima che venga eseguito il blocco di loop e chiude il loop se falso
  3. Il ripensamento: eseguito ogni volta che viene eseguito il loop loop

Questi tre componenti sono separati l'uno dall'altro da un ;simbolo. Il contenuto di ciascuno di questi tre componenti è facoltativo, il che significa che il seguente è il forloop più minimo possibile:

for (;;) {
    // Do stuff
}

Ovviamente, dovrai includere un if(condition === true) { break; } o un punto if(condition === true) { return; }all'interno di quel for-loop per farlo smettere di funzionare.

Di solito, tuttavia, l'inizializzazione viene utilizzata per dichiarare un indice, la condizione viene utilizzata per confrontare quell'indice con un valore minimo o massimo e il ripensamento viene utilizzato per incrementare l'indice:

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

Utilizzo di un forloop tradizionale per eseguire il loop in un array

Il modo tradizionale per eseguire il loop in un array è questo:

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

Oppure, se si preferisce eseguire il looping all'indietro, procedere come segue:

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

Vi sono, tuttavia, molte varianti possibili, come ad esempio questa:

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

... o questo ...

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

... o questo:

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

Qualunque cosa funzioni meglio è in gran parte una questione di gusti personali e del caso d'uso specifico che stai implementando.

Nota che ognuna di queste varianti è supportata da tutti i browser, inclusi quelli molto vecchi!


Un whileciclo

Un'alternativa a un forloop è un whileloop. Per eseguire il loop in un array, è possibile effettuare ciò:

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

Come i forloop tradizionali , i whileloop sono supportati anche dal più vecchio dei browser.

Inoltre, si noti che ogni ciclo while può essere riscritto come un forciclo. Ad esempio, il whileciclo qui sopra si comporta esattamente allo stesso modo di questo for-loop:

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

For...in e for...of

In JavaScript, puoi anche fare questo:

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

Questo dovrebbe essere usato con cura, tuttavia, poiché non si comporta come un forciclo tradizionale in tutti i casi e ci sono potenziali effetti collaterali che devono essere considerati. Vedi Perché usare "for ... in" con l'iterazione dell'array è una cattiva idea? per ulteriori dettagli.

In alternativa a for...in, ora c'è anche per for...of. L'esempio seguente mostra la differenza tra un for...ofloop e un for...inloop:

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
}

Inoltre, è necessario considerare che nessuna versione di Internet Explorer supporta for...of( Edge 12+ supporta ) e che for...inrichiede almeno Internet Explorer 10.


Array.prototype.forEach()

Un'alternativa a for-loops è Array.prototype.forEach(), che utilizza la sintassi seguente:

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

Array.prototype.forEach() è supportato da tutti i browser moderni, nonché da Internet Explorer 9 e versioni successive.


biblioteche

Infine, anche molte librerie di utilità hanno una propria foreachvariante. AFAIK, i tre più popolari sono questi:

jQuery.each(), in jQuery :

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

_.each(), in Underscore.js :

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

_.forEach(), in Lodash.js :

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

68

Usa il ciclo while ...

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

registri: "uno", "due", "tre"

E per l'ordine inverso, un loop ancora più efficiente

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

registri: "tre", "due", "uno"

O il forciclo classico

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

registri: "uno", "due", "tre"

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


21
Il primo esempio della sintassi "while" non funzionerà se uno degli elementi dell'array è errato.
Chris Cooper,

2
... e questo ciclo while equivale a: for (var i = 0, item; item = items [i]; i ++), che elimina la necessità di dichiarare in anticipo l'indice e le variabili item ...
Stijn de Witt


39

Se vuoi un modo conciso per scrivere un ciclo veloce e puoi iterare al contrario:

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

Questo ha il vantaggio di memorizzare nella cache la lunghezza (simile for (var i=0, len=myArray.length; i<len; ++i)e diversa for (var i=0; i<myArray.length; ++i)) pur essendo meno caratteri da digitare.

Ci sono anche alcune volte in cui dovresti ripetere l'iterazione al contrario, ad esempio quando esegui l' iterazione su un Elenco nodi attivo in cui prevedi di rimuovere elementi dal DOM durante l'iterazione.


16
Per le persone che non ottengono ciò che è così geniale: l'espressione i-- viene prima valutata e consente al ciclo di continuare quando non è falsa ... Successivamente il contatore viene decrementato. Non appena divento zero, uscirà dal ciclo poiché zero è un valore falso in Javascript.
Stijn de Witt,

5
falsish? Intendi la falsità. Atteniamo tutti la terminologia corretta per evitare confusione;)
danwellman,

4
Ho visto il termine falsare usato da persone che considero guru. Se è abbastanza buono per loro, è abbastanza buono per me. Anche un ma deluso nel vedere che il mio commento che è in realtà ontopico e aggiunge spiegazione / intuizione ottiene 0 voti, ma il commento che nitpicks su un termine nel mio commento ottiene 4. Ah bene solo una questione di priorità immagino.
Stijn de Witt

"Memorizzare la lunghezza"? La lunghezza è memorizzata come numero intero nell'array, non viene misurata ogni volta che vi si accede. Non c'è alcun vantaggio qui nel copiare il valore della lunghezza in un'altra variabile.
Mouscellaneous,

1
@Mouscellaneous In questi giorni certamente non c'è; negli anni passati iterando array JavaScript che memorizzavano nella cache la lunghezza sul lato JavaScript (invece di raggiungere l'implementazione) è stato un chiaro guadagno perf (quando si utilizzava la microottimizzazione). Ad esempio, for (var i=0,len=array.length;i<len;++i)era un ciclo comune e ragionevole da scrivere.
Phrogz,

36

Alcuni casi d'uso di looping attraverso un array nel modo di programmazione funzionale in JavaScript:

1. Basta passare in rassegna un array

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 () non è un modo funzionale in senso stretto, in quanto la funzione che assume come parametro di input non dovrebbe restituire un valore, che quindi non può essere considerato come una funzione pura.

2. Controllare se uno degli elementi in un array supera un test

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. Trasforma in un nuovo array

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

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

Nota: il metodo map () crea un nuovo array con i risultati della chiamata di una funzione fornita su ogni elemento dell'array chiamante.

4. Sommare una particolare proprietà e calcolarne la media

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. Creare un nuovo array basato sull'originale ma senza 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. Contare il numero di ciascuna categoria

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. Recupera un sottoinsieme di un array in base a criteri particolari

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

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

Nota: il metodo filter () crea un nuovo array con tutti gli elementi che superano il test implementato dalla funzione fornita.

8. Ordinare un array

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

inserisci qui la descrizione dell'immagine

9. Trova un elemento in un array

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

inserisci qui la descrizione dell'immagine

Il metodo Array.prototype.find () restituisce il valore del primo elemento dell'array che soddisfa la funzione di test fornita.

Riferimenti


30

C'è un modo per farlo in cui hai un ambito implicito molto piccolo nel tuo ciclo e elimina le variabili extra.

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 se vuoi davvero ottenere l'id e avere un forloop davvero classico :

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
}

I browser moderni tutti i metodi di supporto iteratore forEach, map, reduce, filtere una miriade di altri metodi sul prototipo Array .


3
Si noti che alcuni interpreti (ad es. V8) memorizzeranno automaticamente in cache la lunghezza dell'array se il codice viene chiamato abbastanza volte e rileva che la lunghezza non viene modificata dal loop.
Phrogz,

Grazie per le informazioni @Phrogz è vero che ci sono molte ottimizzazioni che la VM può fare, ma dal momento che i browser più vecchi non lo hanno, sarebbe comunque una buona pratica ottimizzarlo perché è così economico.
Gabriel,

1
@Gabriel: Perché? Fornisci esempi del mondo reale che mostrano che non memorizzare nella cache la lunghezza è in realtà un collo di bottiglia delle prestazioni. Seguo l'approccio "l'ottimizzazione prematura è la radice di tutti i mali". Risolverò quel loop che in realtà pone un problema una volta che lo incontro ...
Stijn de Witt

1
@StijndeWitt imo è solo una questione stilistica. Onestamente non uso più nemmeno per i loop, basandomi invece sul trattino basso per cose come _.each, _.map ecc. Per fare queste cose. Quando ho scritto dei loop in questo modo, ho memorizzato la lunghezza della cache principalmente in modo tale che tutte le mie dichiarazioni variabili fossero in un posto, nella parte superiore della mia funzione. Seguire il mio consiglio al riguardo è irrilevante per qualsiasi applicazione nel mondo reale. L'ottimizzazione precoce è super negativa, ma se l'ottimizzazione deriva da decisioni stilistiche, non penso che sia davvero importante.
Gabriel

1
@Gabriel Credo che JavaScript supporti già la funzione mappa su array, non è necessario introdurre una lib aggiuntiva per questo.
Noz,

28

Esistono vari modi per eseguire il loop nell'array in JavaScript.

Loop generico:

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

ES5 per ciascuno:

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

Dai un'occhiata a questo per informazioni dettagliate o puoi anche controllare MDN per il looping di un array in JavaScript e usare jQuery per jQuery .


27

Consiglio vivamente di utilizzare la libreria underscore.js . Fornisce varie funzioni che è possibile utilizzare per scorrere su array / raccolte.

Per esempio:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...

7
Per i nuovi scopritori di questa domanda, vorrei solo sottolineare Lo-Dash , un successore spirituale di Underscore che migliora su di essa in molti modi.
Mark Reed,

3
Perché usare underscorese ECMA-262 è stata aggiunta la forEachmethor. Il codice nativo è sempre migliore.
Walter Chapilliquen - wZVanG,

27

Ciclo di array:

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

Ciclo di oggetti:

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

27

, puoi fare lo stesso in JavaScript usando un loop, ma non solo , ci sono molti modi per fare un loop su array in JavaScript. Immagina di avere questo array sotto, e ti piacerebbe fare un loop su di esso:

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

Queste sono le soluzioni:

1) Per loop

Un forloop è un modo comune di eseguire il looping di matrici in JavaScript, ma non è considerato la soluzione più veloce per matrici di grandi dimensioni:

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

2) Mentre loop

Un ciclo while è considerato il modo più veloce per eseguire il ciclo attraverso lunghe matrici, ma di solito è meno utilizzato nel codice JavaScript:

let i=0;

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

3) Fai mentre
A do whilesta facendo la stessa cosa whilecon qualche differenza di sintassi come di seguito:

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

Questi sono i modi principali per fare loop JavaScript, ma ci sono alcuni altri modi per farlo.

Inoltre usiamo un for inloop per il looping su oggetti in JavaScript.

Anche guardare i map(), filter(), reduce()funzioni, ecc su un array in JavaScript. Possono fare le cose molto più velocemente e meglio dell'uso whilee for.

Questo è un buon articolo se ti piace saperne di più sulle funzioni asincrone sugli array in JavaScript.

La programmazione funzionale ha fatto un bel tuffo nel mondo dello sviluppo in questi giorni. E per una buona ragione: le tecniche funzionali possono aiutarti a scrivere più codice dichiarativo che è più facile da capire a colpo d'occhio, refactor e test.

Uno dei cardini della programmazione funzionale è l'uso speciale di liste e operazioni di lista. E quelle cose sono esattamente come sembrano: matrici di cose e le cose che fai a loro. Ma la mentalità funzionale li tratta in modo leggermente diverso da quanto ci si potrebbe aspettare.

Questo articolo darà uno sguardo da vicino a ciò che mi piace chiamare le operazioni della lista "tre grandi": mappa, filtro e riduzione. Avvolgere la testa attorno a queste tre funzioni è un passo importante verso la capacità di scrivere un codice funzionale pulito e apre le porte a tecniche estremamente potenti di programmazione funzionale e reattiva.

Significa anche che non dovrai mai più scrivere un ciclo for.

Leggi di più >> qui :


Esiste davvero una differenza di prestazioni prima di un ciclo for e di un ciclo while quando si scorre in un array? Avevo l'impressione che le differenze fossero principalmente sintattiche
karité il

24

Se qualcuno è interessato al lato prestazionale dei molteplici meccanismi disponibili per le iterazioni di array, ho preparato i seguenti test JSPerf:

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

Risultati delle prestazioni

risultati:

L' for()iteratore tradizionale è di gran lunga il metodo più veloce, specialmente se utilizzato con la lunghezza dell'array memorizzata nella cache .

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

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

L' Array.prototype.forEach()ei Array.prototype.map()metodi sono approssimazioni più lente, probabilmente come conseguenza della chiamata di funzione .


è meglio usare i = i +1invece dii++
DarckBlezzer il

2
Potrebbe essere migliorato: si prega di utilizzare: ++ i invece di i ++, questo eviterà un oggetto temporaneo. Quindi riduce l'utilizzo della memoria e il tempo della CPU (nessuna allocazione richiesta)!
PowerStat,

@PowerStat puoi fornire un link o un riferimento al riguardo? Non l'ho mai sentito, sembra interessante ...
colxi,

1
@colxi Per cose così interessanti dovresti leggere le cose hardcore su C ++ di Herb Sutter e Scott Meyers. La cosa ++ i vs i ++ proviene dal libro: C ++ eccezionale: 47 puzzle ingegneristici, problemi di programmazione e soluzioni - Penso che potresti trovarlo anche su gotw.ca ma che può essere provato per ogni linguaggio di programmazione.
PowerStat,

21

Se stai usando la libreria jQuery, considera l'utilizzo di http://api.jquery.com/jQuery.each/

Dalla documentazione:

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

Ritorna: oggetto

Descrizione: una funzione di iteratore generico, che può essere utilizzata per iterare senza soluzione di continuità su oggetti e array. Le matrici e gli oggetti simili a array con una proprietà length (come l'oggetto argomenti di una funzione) sono iterati dall'indice numerico, da 0 a lunghezza-1. Altri oggetti vengono ripetuti tramite le proprietà denominate.

La $.each()funzione non è la stessa $(selector).each()utilizzata per iterare, esclusivamente, su un oggetto jQuery. La $.each() funzione può essere utilizzata per scorrere su qualsiasi raccolta, sia essa una mappa (oggetto JavaScript) o un array. Nel caso di un array, al callback viene passato ogni volta un indice di array e un valore di array corrispondente. (È possibile accedere al valore anche tramite la thisparola chiave, ma Javascript lo avvolgerà sempre thiscome Objectse fosse una semplice stringa o valore numerico.) Il metodo restituisce il suo primo argomento, l'oggetto che è stato ripetuto.


9
jQuery per tutto?
Eccezione

6
Concordato con eccezione. Non sottovalutare l'impatto delle dipendenze extra. Vorrei sconsigliare questo fatto tranne nel codice che sta già utilizzando pesantemente jQuery comunque.
Stijn de Witt,

2
Aggiornamento: Al giorno d'oggi, puoi usare Array.forEach per ottenere lo stesso effetto con le matrici native.
Stijn de Witt,

21

Non ho ancora visto questa variazione, che personalmente mi piace di più:

Dato un array:

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

Puoi eseguirne il ciclo senza mai accedere alla proprietà 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);
}

Vedi questo JsFiddle che dimostra che: http://jsfiddle.net/prvzk/

Questo funziona solo per array che non sono sparsi. Ciò significa che esiste effettivamente un valore in ciascun indice dell'array. Tuttavia, ho scoperto che in pratica non uso quasi mai array sparsi in JavaScript ... In questi casi, di solito è molto più facile usare un oggetto come mappa / tabella hash. Se si dispone di una matrice sparsa e si desidera eseguire il ciclo su 0 .. lunghezza-1, è necessario il costrutto for (var i = 0; i <someArray.length; ++ i), ma è comunque necessario un ifall'interno del ciclo per verificare se l'elemento nell'indice corrente è effettivamente definito.

Inoltre, come menziona CMS in un commento di seguito, è possibile utilizzarlo solo su array che non contengono valori falsi. La matrice di stringhe dell'esempio funziona, ma se si hanno stringhe vuote o numeri che sono 0 o NaN, ecc., Il ciclo si interromperà prematuramente. Ancora una volta in pratica questo non è quasi mai un problema per me, ma è qualcosa da tenere a mente, il che lo rende un loop a cui pensare prima di usarlo ... Ciò potrebbe squalificarlo per alcune persone :)

Quello che mi piace di questo loop è:

  • È breve da scrivere
  • Non è necessario accedere (per non parlare della cache) alla proprietà length
  • L'elemento a cui accedere viene automaticamente definito all'interno del corpo del loop sotto il nome selezionato.
  • Si combina in modo molto naturale con array.push e array.splice per utilizzare array come elenchi / stack

Il motivo per cui funziona è che la specifica dell'array impone che quando si legge un elemento da un indice> = la lunghezza dell'array, verrà restituito indefinito. Quando scrivi in ​​una tale posizione aggiornerà effettivamente la lunghezza.

Per me, questo costrutto emula più da vicino la sintassi Java 5 che adoro:

for (String item : someArray) {
}

... con l'ulteriore vantaggio di conoscere anche l'indice corrente all'interno del loop


14
Si noti che con questo approccio il ciclo si arresta appena viene rilevato un valore falsey , come una stringa vuota, 0, false, NaN, nullo undefined, anche prima iraggiunge la lunghezza, ad esempio: jsfiddle.net/prvzk/1
CMS

3
La condizione del loop potrebbe essere (item=someArray[i]) !== undefined.
daniel1426,

18

Esiste un metodo per scorrere solo le proprietà dei propri oggetti, escluse quelle del prototipo:

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

ma continuerà a scorrere su proprietà definite dall'utente.

In JavaScript qualsiasi proprietà personalizzata può essere assegnata a qualsiasi oggetto, incluso un array.

Se si desidera eseguire l'iterazione su array parsimoniosi for (var i = 0; i < array.length; i++) if (i in array)o array.forEachcon es5shimdovrebbe essere utilizzato.


E che ne dici di usare for (var i in array) if (++i)?
Daniel Sokolowski,

15

Ci sono un paio di modi per farlo in JavaScript. I primi due esempi sono esempi JavaScript. Il terzo fa uso di una libreria JavaScript, ovvero jQuery che utilizza la .each()funzione.

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>


for...indovrebbe essere evitato per gli oggetti simili a array
brk

15

Il modo più elegante e veloce

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

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


Modificato (perché mi sbagliavo)


Confronto tra i metodi per eseguire il looping di una matrice di 100000 articoli ed eseguire ogni volta un'operazione minima con il nuovo valore.

Preparazione:

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

test:

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

Questo ciclo sembra non seguire l'ordine degli elementi nell'array.
Deniz Ozger,

Il mio test è stato sbagliato. È corretto, mostrando tutti i LOOP ora. jsperf.com/native-loop-performance/16
molokoloco

@bergi ha ragione. Questo loop cancella l'array mentre lo attraversa. Non è quello che vuoi nella maggior parte dei casi.
Stijn de Witt,

4
interruzioni su articoli falsi.
njzk2,

12

L'approccio ottimizzato consiste nel memorizzare nella cache la lunghezza dell'array e utilizzare il modello var singolo inizializzando tutte le variabili con una parola chiave var singola.

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

Se l'ordine di iterazione non ha importanza di quanto dovresti provare a ciclo inverso, è più veloce in quanto riduce il test delle condizioni generali e il decremento è in una sola istruzione:

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

o meglio e più pulito da usare mentre loop:

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

12

In JavaScript, ci sono così tante soluzioni per eseguire il looping di un array.

I seguenti codici sono popolari

/** 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

Se vuoi usare jQuery, ha un buon esempio nella sua documentazione:

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

12

Il modo migliore secondo me è usare la funzione Array.forEach. Se non puoi usarlo, suggerirei di ottenere il polyfill da MDN. Per renderlo disponibile, è sicuramente il modo più sicuro per scorrere su un array in JavaScript.

Array.prototype.forEach ()

Quindi, come altri hanno suggerito, questo è quasi sempre quello che vuoi:

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

Ciò garantisce che tutto ciò che è necessario nell'ambito dell'elaborazione dell'array rimanga all'interno di tale ambito e che si stiano elaborando solo i valori dell'array, non le proprietà dell'oggetto e altri membri, che è ciò che for .. fa.

Usando un normale stile C. for ciclo in funziona nella maggior parte dei casi. È importante ricordare che tutto all'interno del ciclo condivide il suo ambito con il resto del programma, {} non crea un nuovo ambito.

Quindi:

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

produrrà "11" - che può essere o meno quello che vuoi.

Un esempio js funzionante: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/


10

Non è identico al 100%, ma simile:

   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
    }


1
Sembra che ciò si verificherebbe con problemi simili a quelli degli usi con un oggetto array, in quanto anche le variabili membro del prototipo verrebbero rilevate da for in.
Kzqai,

9

Ad esempio, ho usato in una console Firefox:

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

9
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

Molto più pulito ...


Non è molto pulito rispetto a z.forEach(j => console.log(j));.
Sapphire_Brick

9

Risposta breve: si. Puoi farlo con questo:

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

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

In una console del browser, puoi vedere qualcosa come "element1", "element2", ecc., Stampato.


9

Puoi usare Array.prototype.forEach(...):

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

Oppure Array.prototype.map(...):

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

O il jquery o per i modi loop precedentemente menzionati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.