Iterare sugli Array in JavaScript
- In JavaScript, possiamo iterare sugli array utilizzando il ciclo
for/of
, il metodoforEach()
, o un ciclofor
tradizionale. - Il ciclo
for/of
è semplice e intuitivo, mentreforEach()
offre un approccio funzionale. - Possiamo anche utilizzare il metodo
entries()
per ottenere sia l'indice che il valore durante l'iterazione. - Il ciclo
for
tradizionale è più verboso ma offre un controllo preciso sull'iterazione, ed è utile in situazioni in cui le prestazioni sono critiche.
Iterazione sugli Array
A partire da ES6, il modo più semplice per scorrere ciascuno degli elementi di un array (o qualsiasi oggetto iterabile) è con il ciclo for/of
, che abbiamo visto in dettaglio nelle lezioni precedenti. Il ciclo for/of
itera su ogni elemento di un array, uno alla volta, e possiamo usare una variabile per tenere traccia dell'elemento corrente. Ecco un esempio:
// Creiamo un array di lettere
// a partire da una stringa
// con l'operatore spread
let lettere = [..."Ciao mondo"];
let stringa = "";
// Con un ciclo for riassembliamo la stringa originale
for(let lettera of lettere) {
stringa += lettera;
}
console.log(stringa); // => "Ciao mondo"
L'iteratore di array integrato che il ciclo for/of
utilizza restituisce gli elementi di un array in ordine crescente. Non ha un comportamento speciale per gli array sparsi e restituisce semplicemente undefined
per qualsiasi elemento dell'array che non esiste.
Se vogliamo utilizzare un ciclo for/of
per un array e abbiamo bisogno di conoscere l'indice di ciascun elemento dell'array, si può adoperare il metodo entries()
dell'array, insieme all'assegnazione destrutturante, in questo modo:
let lettere = [..."Ciao mondo"];
let alterni = "";
for(let [indice, lettera] of lettere.entries()) {
// lettere agli indici pari
if (indice % 2 === 0) alterni += lettera;
}
console.log(alterni) // => "Ca od"
Un altro buon modo per iterare gli array è con forEach()
. Non è una nuova forma del ciclo for
, ma un metodo dell'array che offre un approccio funzionale all'iterazione degli array. Passiamo una funzione al metodo forEach()
di un array, e forEach()
invoca la nostra funzione una volta su ciascun elemento dell'array:
let lettere = [..."Ciao mondo"];
let maiuscolo = "";
// Si noti la sintassi per le funzioni anonime
lettere.forEach(lettera => {
maiuscolo += lettera.toUpperCase();
});
console.log(maiuscolo); // => "CIAO MONDO"
Come ci si può aspettare, forEach()
itera l'array in ordine, e in realtà passa l'indice dell'array alla nostra funzione come secondo argomento, che a volte può essere utile. A differenza del ciclo for/of
, il forEach()
è consapevole degli array sparsi e non invoca la nostra funzione per elementi che non ci sono.
Nelle prossime lezioni studieremo il metodo forEach()
in maggiore dettaglio. Vedremo anche i metodi correlati come map()
e filter()
che eseguono tipi specializzati di iterazione degli array.
Possiamo anche scorrere gli elementi di un array con un ciclo for
tradizionale. Questo ciclo è più verboso, ma può essere utile in situazioni in cui abbiamo bisogno di un controllo più preciso sull'iterazione:
let lettere = [..."Ciao mondo"];
let vocali = "";
// Iteriamo su ogni indice dell'array
for(let i = 0; i < lettere.length; i++) {
// Otteniamo l'elemento a quell'indice
let lettera = lettere[i];
// Se l'elemento è una vocale, lo aggiungiamo alla stringa
// delle vocali
// Usiamo un test con espressione regolare
if (/[aeiou]/.test(lettera)) {
// Aggiungiamo la lettera alla stringa delle vocali
vocali += lettera;
}
}
console.log(vocali); // => "iaoo"
In cicli annidati, o altri contesti dove le prestazioni sono critiche, a volte possiamo vedere questo ciclo di iterazione di array di base scritto in modo che la lunghezza dell'array venga cercata solo una volta piuttosto che ad ogni iterazione. Entrambe le seguenti forme di ciclo for
sono idiomatiche, anche se non particolarmente comuni, e con gli interpreti JavaScript moderni, non è affatto chiaro se abbiano o meno un impatto sulle prestazioni:
// Salviamo la lunghezza dell'array in una variabile locale
for(let i = 0, lun = lettere.length; i < lun; i++) {
// il corpo del ciclo rimane lo stesso
}
// Iteriamo all'indietro dalla fine dell'array all'inizio
for(let i = lettere.length-1; i >= 0; i--) {
// il corpo del ciclo rimane lo stesso
}
Questi esempi assumono che l'array sia denso e che tutti gli elementi contengano dati validi. Se questo non è il caso, dovremmo testare la presenza degli elementi dell'array prima di usarli. Se vogliamo saltare elementi undefined
e inesistenti, potremmo scrivere:
for(let i = 0; i < a.length; i++) {
// Salta elementi undefined e inesistenti
if (a[i] === undefined) continue;
// corpo del ciclo qui
}