Articolo originale: https://www.freecodecamp.org/news/complete-introduction-to-the-most-useful-javascript-array-methods/

Se sei uno sviluppatore JavaScript e vuoi migliorare le tue abilità, allora dovresti conoscere i metodi per array più usati in ES5 e ES6+.

Questi metodi rendono più semplice la scrittura del codice, che risulterà più pulito e facile da comprendere.

In questo articolo, esploreremo alcuni dei metodi per array più conosciuti e utilizzati. Iniziamo!

Il metodo Array.forEach

Il metodo Array.forEach ha la seguente sintassi:

Array.forEach(function callback(elemento [, indice[, array]])[, thisArg]);

Il metodo forEach esegue la funzione callback fornita per ogni elemento dell'array.

Dai un'occhiata al codice qui sotto:

const months = ['January', 'February', 'March', 'April'];

months.forEach(function(month) {
  console.log(month);
});

/* output

January
February
March
April

*/

Ecco una demo su Code Pen.

Qui, all'interno della funzione callback del loop forEach, ogni elemento dell'array viene passato automaticamente come primo parametro della funzione.

Il codice del loop for equivalente ha questo aspetto:

const months = ['January', 'February', 'March', 'April'];

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

/* output

January
February
March
April

*/

Ecco una demo su Code Pen.

Ciò che devi tenere a mente è che il metodo forEach non restituisce nessun valore.

Guarda il codice qui sotto:

const months = ['January', 'February', 'March', 'April'];
const returnedValue = months.forEach(function (month) {
  return month;
});

console.log('returnedValue: ', returnedValue); // undefined

Ecco una demo su Code Pen.

Nota che forEach viene usato soltanto per iterare su un array ed eseguire un'elaborazione o un consulto. Non restituisce nessun valore di ritorno, neanche se restituisci esplicitamente un valore dalla funzione callback (ciò significa che il valore di ritorno nell'esempio precedente sarà undefined).

In tutti gli esempi precedenti, abbiamo usato soltanto il primo parametro della funzione callback. Ma la funzione callback può ricevere anche due parametri aggiuntivi, che sono:

  • l'indice dell'elemento dell'iterazione corrente
  • l'array originale su cui si sta iterando
const months = ['January', 'February', 'March', 'April'];

months.forEach(function(month, index, array) {
  console.log(month, index, array);
});

/* output

January 0 ["January", "February", "March", "April"]
February 1 ["January", "February", "March", "April"]
March 2 ["January", "February", "March", "April"]
April 3 ["January", "February", "March", "April"]

*/

Ecco una demo su Code Pen.

A seconda dei requisiti, potresti trovare utile usare i parametri indice e array.

Vantaggi dell'uso di forEach invece di un loop for

  • Usare forEach rende il codice più corto e semplice da capire.
  • Usando forEach non dobbiamo tenere traccia degli elementi disponibili nell'array. Quindi si evita di creare una variabile contatore extra.
  • Usare forEach rende più semplice il debugging perché non ci sono variabili extra per iterare sull'array.
  • forEach si ferma automaticamente quando termina di iterare sugli elementi dell'array.

Supporto browser

  • Tutti i browser moderni e Internet Explorer (IE) versione 9 e successive
  • Microsoft Edge versione 12 e successive

Il metodo Array.map

Array.map è il metodo più utile e ampiamente usato tra tutti gli altri metodi.

Il metodo Array.map ha la seguente sintassi:

Array.map(function callback(elemento[, indice[, array]]) {
    // Restituisce elementi per un nuovo array
}[, thisArg])

Il metodo map esegue la funzione fornita per ogni elemento dell'array e restituisce un nuovo array trasformato.

Dai un'occhiata al codice qui sotto:

const months = ['January', 'February', 'March', 'April'];
const transformedArray = months.map(function (month) {
  return month.toUpperCase();
});

console.log(transformedArray); // ["JANUARY", "FEBRUARY", "MARCH", "APRIL"]

Ecco una demo su Code Pen.

Nel codice qui sopra, all'interno della funzione callback, ogni elemento viene trasformato in maiuscolo e restituito.

Il loop for equivalente ha questo aspetto:

const months = ['January', 'February', 'March', 'April'];
const converted = [];

for(let i = 0; i < months.length; i++) {
 converted.push(months[i].toUpperCase());
};

console.log(converted); // ["JANUARY", "FEBRUARY", "MARCH", "APRIL"]

Ecco una demo su Code Pen.

Usare map aiuta ad evitare di creare un array separato per contenere gli elementi convertiti. Quindi salva spazio in memoria e il codice risulta più pulito:

const months = ['January', 'February', 'March', 'April'];

console.log(months.map(function (month) {
  return month.toUpperCase();
})); // ["JANUARY", "FEBRUARY", "MARCH", "APRIL"]

Ecco una demo su Code Pen.

Nota che il metodo map restituisce un nuovo array della stessa lunghezza dell'array originale.

La differenza tra i metodi forEach e map è che forEach è usato solamente per iterare e non restituisce nulla. D'altro canto, il metodo map non cambia l'array originale, ma restituisce un nuovo array della stessa lunghezza dell'array originale.

Dai un'occhiata al codice qui sotto:

const users = [
  {
    first_name: 'Mike',
    last_name: 'Sheridan'
  },
  {
    first_name: 'Tim',
    last_name: 'Lee'
  },
  {
    first_name: 'John',
    last_name: 'Carte'
  }
];

const usersList = users.map(function (user) {
  return user.first_name + ' ' + user.last_name;
});

console.log(usersList); // ["Mike Sheridan", "Tim Lee", "John Carte"]

Ecco una demo su Code Pen.

Utilizzando l'array di oggetti e il metodo map, generiamo facilmente un solo array con nome e cognome concatenati.

Nel codice qui sopra, abbiamo usato l'operatore + per concatenare i due valori, ma  in ES6 è più comune usare la sintassi template literal come mostrato qui sotto:

const users = [
  {
    first_name: 'Mike',
    last_name: 'Sheridan'
  },
  {
    first_name: 'Tim',
    last_name: 'Lee'
  },
  {
    first_name: 'John',
    last_name: 'Carte'
  }
];

const usersList = users.map(function (user) {
  return `${user.first_name} ${user.last_name}`;
});

console.log(usersList); // ["Mike Sheridan", "Tim Lee", "John Carte"]

Ecco una demo su Code Pen.

Il metodo map è utile anche se vuoi estrarre solo dei dati specifici da un array, come in questo caso:

const users = [
  {
    first_name: 'Mike',
    last_name: 'Sheridan',
    age: 30
  },
  {
    first_name: 'Tim',
    last_name: 'Lee',
    age: 45
  },
  {
    first_name: 'John',
    last_name: 'Carte',
    age: 25
  }
];

const surnames = users.map(function (user) {
  return user.last_name;
});

console.log(surnames); // ["Sheridan", "Lee", "Carte"]

Ecco una demo su Code Pen.

Nel codice qui sopra, abbiamo estratto solo i cognomi di ogni utente, memorizzandoli in un array.

Possiamo usare map anche per generare un array con un contenuto dinamico, come mostrato qui sotto:

const users = [
  {
    first_name: 'Mike',
    location: 'London'
  },
  {
    first_name: 'Tim',
    location: 'US'
  },
  {
    first_name: 'John',
    location: 'Australia'
  }
];

const usersList = users.map(function (user) {
  return `${user.first_name} lives in ${user.location}`;
});

console.log(usersList); // ["Mike lives in London", "Tim lives in US", "John lives in Australia"]

Ecco una demo su Code Pen.

Nota che nel codice qui sopra non abbiamo cambiato l'array users originale. Abbiamo creato un nuovo array con un contenuto dinamico, perché map restituisce sempre un nuovo array.

Vantaggi dell'uso del metodo map

  • Aiuta a generare rapidamente un nuovo array senza cambiare l'array originale
  • Aiuta a generare un array con contenuto dinamico in base a ogni elemento
  • Permette di estrarre rapidamente qualsiasi elemento dell'array
  • Genera un array della stessa lunghezza dell'array originale

Supporto browser

  • Tutti i browser moderni e Internet Explorer (IE) versione 9 e successive
  • Microsoft Edge versione 12 e successive

Il metodo Array.find

Il metodo Array.find ha la seguente sintassi:

Array.find(function callback(elemento [, indice[, array]])[, thisArg])
Il metodo find restituisce il valore del primo elemento nell'array che soddisfa la condizione di test fornita.

Il metodo find prende una funzione callback come primo argomento e la esegue per tutti gli elementi dell'array. Ogni elemento viene passato come primo parametro alla funzione callback.

Supponiamo di avere la seguente lista di impiegati:

const employees = [
 { name: "David Carlson", age: 30 },
 { name: "John Cena", age: 34 },
 { name: "Mike Sheridan", age: 25 },
 { name: "John Carte", age: 50 }
];

e di voler trovare l'entrata corrispondente all'impiegato di nome John. In questo caso, possiamo usare il metodo find come mostrato qui sotto:

const employee = employees.find(function (employee) {
  return employee.name.indexOf('John') > -1;
});

console.log(employee); // { name: "John Cena", age: 34 }

Ecco una demo su Code Pen.

Anche se c'è "John Carte" nella lista, il metodo find si fermerà quando trova la prima corrispondenza. Quindi non restituirà l'oggetto con il nome "John Carte".

Il loop for equivalente al codice qui sopra ha il seguente aspetto:

const employees = [
 { name: "David Carlson", age: 30 },
 { name: "John Cena", age: 34 },
 { name: "Mike Sheridan", age: 25 },
 { name: "John Carte", age: 50 }
];

let user;

for(let i = 0; i < employees.length; i++) {
  if(employees[i].name.indexOf('John') > -1) {
    user = employees[i];
    break;
  }
}

console.log(user); // { name: "John Cena", age: 34 }

Ecco una demo su Code Pen.

Come puoi vedere, usare il normale loop for rende il codice più lungo e difficile da capire. Ma con il metodo find, puoi scrivere lo stesso codice in modo semplice.

Vantaggi dell'uso del metodo find

  • Consente di trovare velocemente qualsiasi elemento senza scrivere troppo codice
  • Si ferma non appena trova una corrispondenza, quindi non c'è bisogno di un'istruzione break aggiuntiva

Supporto browser

  • Tutti i browser moderni tranne Internet Explorer (IE)
  • Microsoft Edge versione 12 e successive

Il metodo Array.findIndex

Il metodo Array.findIndex ha la seguente sintassi:

Array.findIndex(function callback(elemento[, indice[, array]])[, thisArg])

Il metodo findIndex restituisce l'indice del primo elemento dell'array che soddisfa la condizione di test fornita. Altrimenti restituisce -1, indicando che non c'è nessun elemento che ha passato il test.

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridan', age: 25 },
  { name: 'John Carte', age: 50 }
];

const index = employees.findIndex(function (employee) {
  return employee.name.indexOf('John') > -1;
});

console.log(index); // 1

Ecco una demo su Code Pen.

In questo caso, otteniamo come output 1, che è l'indice del primo oggetto con il nome John. Nota che gli indici partono da zero.

Il loop for equivalente al codice dell'esempio qui sopra ha questo aspetto:

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridan', age: 25 },
  { name: 'John Carte', age: 50 }
];

let index = -1;

for(let i = 0; i < employees.length; i++) {
  if(employees[i].name.indexOf('John') > -1) {
    index = i;
    break;
  }
}

console.log(index); // 1

Ecco una demo su Code Pen.

Vantaggi dell'uso del metodo findIndex

  • Consente di trovare velocemente l'indice di un elemento senza scrivere molto codice
  • Termina di iterare non appena trova una corrispondenza, quindi non c'è bisogno di un'istruzione break aggiuntiva
  • Possiamo trovare l'indice usando anche il metodo find, ma usare findIndex rende tutto più semplice ed evita di creare variabili extra per memorizzare l'indice

Supporto browser

  • Tutti i browser moderni tranne Internet Explorer (IE)
  • Microsoft Edge versione 12 e successive

Il metodo Array.filter

Il metodo Array.filter ha la seguente sintassi:

Array.filter(function callback(elemento[, indice[, array]])[, thisArg])

Il metodo filter restituisce un nuovo array con tutti gli elementi che soddisfano la condizione di test fornita.

Il metodo filter prende una funzione callback come primo argomento e la esegue per ogni elemento dell'array. Ogni elemento dell'array viene passato come primo parametro della funzione callback.

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridan', age: 25 },
  { name: 'John Carte', age: 50 }
];

const employee = employees.filter(function (employee) {
  return employee.name.indexOf('John') > -1;
});

console.log(employee); // [ { name: "John Cena", age: 34 }, { name: "John Carte", age: 50 }]

Ecco una demo su Code Pen.

Come puoi vedere nel codice qui sopra, usare filter aiuta a trovare tutti gli elementi di un array che corrispondono alla condizione di test specificata.

Quindi usando filter le iterazioni non vengono stoppate quando viene trovata una corrispondenza, ma continuano per verificare che gli altri elementi corrispondano alla condizione. Poi tutti gli elementi che soddisfano la condizione vengono restituiti.

La differenza principale tra find e filter è che find restituisce soltanto il primo elemento dell'array che soddisfa la condizione, mentre filter li restituisce tutti.

Nota che il metodo filter restituisce sempre un array. Se nessun elemento supera la condizione di test, verrà restituito un array vuoto.

Il loop for equivalente al codice dell'esempio qui sopra è:

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridan', age: 25 },
  { name: 'John Carte', age: 50 }
];

let filtered = [];

for(let i = 0; i < employees.length; i++) {
 if(employees[i].name.indexOf('John') > -1) {
   filtered.push(employees[i]);
 }
}

console.log(filtered); // [ { name: "John Cena", age: 34 }, { name: "John Carte", age: 50 }]

Ecco una demo su Code Pen.

Vantaggi dell'uso del metodo filter

  • Consente di trovare velocemente tutti gli elementi dell'array che soddisfano i criteri di ricerca
  • Restituisce sempre un array anche se non c'è corrispondenza, quindi evita di dover scrivere condizioni if extra
  • Evita la necessità di creare una variabile extra per memorizzare gli elementi filtrati

Supporto browser

  • Tutti i browser moderni e Internet Explorer (IE) versione 9 e successive
  • Microsoft Edge versione 12 e successive

Il metodo Array.every

Il metodo Array.every ha la seguente sintassi:

Array.every(function callback(elemento[, indice[, array]])[, thisArg])

Il metodo every testa se tutti gli elementi nell'array supera una condizione fornita e restituisce un valore booleano true o false.

Supponi di avere un array di numeri e di voler verificare se ogni elemento dell'array è un numero positivo. Possiamo usare il metodo every per questo.

let numbers = [10, -30, 20, 50];

let allPositive = numbers.every(function (number) {
  return number > 0;
});
console.log(allPositive); // false 

numbers = [10, 30, 20, 50];

allPositive = numbers.every(function (number) {
  return number > 0;
});
console.log(allPositive); // true

Immagina di avere un modulo di registrazione e di voler verificare se tutti i campi richiesti sono stati compilati o no prima dell'invio del modulo. Puoi usare il metodo every per verificare facilmente il valore di ogni campo.

window.onload = function () {
  const form = document.getElementById('registration_form');
  form.addEventListener('submit', function (event) {
    event.preventDefault();
    const fields = ['first_name', 'last_name', 'email', 'city'];
    const allFieldsEntered = fields.every(function (fieldId) {
      return document.getElementById(fieldId).value.trim() !== '';
    });

    if (allFieldsEntered) {
      console.log('All the fields are entered');
      // All the field values are entered, submit the form
    } else {
      alert('Please, fill out all the field values.');
    }
  });
};

Ecco una demo su Code Pen.

All'interno della funzione callback del metodo every, abbiamo verificato se ogni campo è vuoto e restituito un valore booleano.

Nel codice precedente, il metodo every restituisce true se per tutti gli elementi dell'array fields la funzione callback restituisce il valore true.

Se la funzione callback restituisce un valore false per uno qualsiasi degli elementi dell'array fields, allora il metodo every restituirà false come risultato.

Vantaggi dell'uso del metodo every

  • Consente di verificare rapidamente se  tutti gli elementi di un array corrispondono a un certo criterio senza scrivere molto codice

Supporto browser

  • Tutti i browser moderni e Internet Explorer (IE) versione 9 e successive
  • Microsoft Edge versione 12 e successive

Il metodo Array.some

Il metodo Array.some ha la seguente sintassi:

 Array.some(function callback(elemento[, indice[, array]])[, thisArg]

Il metodo some testa se almeno un elemento nell'array supera la condizione data dalla funzione fornita e restituisce un valore booleano true o false.

Restituisce true una volta che trova la prima corrispondenza e restituisce false se non ne trova nessuna.

Supponi di avere un array di numeri e di voler verificare se contiene almeno un numero positivo. Per farlo puoi usare il metodo some.

let numbers = [-30, 40, 20, 50];

let containsPositive = numbers.some(function (number) {
  return number > 0;
});
console.log(containsPositive); // true 

numbers = [-10, -30, -20, -50];

containsPositive = numbers.every(function (number) {
  return number > 0;
});
console.log(containsPositive); // false

Esistono alcune situazioni utili per usare il metodo some.

Metodo some esempio 1:

Diciamo di avere una lista di impiegati e di voler verificare se un particolare impiegato è presente nell'array o meno. Vogliamo anche sapere l'indice della posizione dell'impiegato se viene trovato.

Quindi, invece di usare i metodi find e findIndex separatamente, possiamo usare il metodo some per fare entrambe le cose.

const employees = [
  { name: 'David Carlson', age: 30 },
  { name: 'John Cena', age: 34 },
  { name: 'Mike Sheridon', age: 25 },
  { name: 'John Carte', age: 50 }
];

let indexValue = -1;
const employee = employees.some(function (employee, index) {
  const isFound = employee.name.indexOf('John') > -1;
  if (isFound) {
    indexValue = index;
  }
  return isFound;
});

console.log(employee, indexValue); // true 1

Ecco una demo su Code Pen.

Metodo some – esempio 2:

I metodi per array forEach, map e filter vengono eseguiti dal primo all'ultimo elemento di un array. Non c'è modo di fermare le iterazioni una volta che un particolare elemento viene trovato.

In questi casi possiamo usare il metodo some. I metodi map, forEach e some prendono gli stessi parametri nella funzione callback:

  • Il primo parametro è il valore effettivo
  • Il secondo parametro è l'indice
  • Il terzo parametro è l'array originale

Il metodo some stoppa le iterazioni sull'array una volta che trova una particolare corrispondenza, come si può vedere nell'esempio 1.

Vantaggi dell'uso del metodo some

  • Consente di verificare velocemente se alcuni degli elementi corrispondono a un certo criterio senza scrivere molto codice
  • Consente di uscire rapidamente dal loop, cosa che non è possibile con gli altri metodi visti in precedenza

Supporto browser

  • Tutti i browser moderni e Internet Explorer (IE) versione 9 e successive
  • Microsoft Edge versione 12 e successive

Il metodo Array.reduce

Il metodo Array.reduce ha la seguente sintassi:

Array.reduce(function callback(accumulatore, valoreCorrente[, indice[, array]]) {} [, valoreIniziale])

Il metodo reduce esegue una funzione reducer fornita su ogni elemento dell'array e restituisce un singolo valore di output.

Nota che l'output del metodo reduce è sempre un singolo valore. Può essere un oggetto, un numero, una stringa, un array e così via. Dipende da cosa vuoi che generi come output il metodo reduce, ma sarà sempre un singolo valore.

Supponi di voler trovare la somma di tutti i numeri in un array. Per questo puoi usare il metodo reduce.

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

const sum = numbers.reduce(function(accumulator, number) {
  return accumulator + number; 
}, 0);

console.log(sum); // 15

Ecco una demo su Code Pen.

Il metodo reduce accetta una funzione callback che riceve accumulator, number, index e array come valori. Nel codice qui sopra, abbiamo usato solo accumulator e number.

accumulator conterrà il valore iniziale da usare nell'array, il quale determina il tipo di dato restituito dal metodo reduce.

number è il secondo parametro della funzione callback che conterrà l'elemento dell'array durante ogni iterazione del loop.

Nel codice qui sopra, abbiamo usato 0 come valore iniziale per accumulator. Quindi la prima volta che la funzione callback viene eseguita, accumulator + number sarà 0 + 1 = 1 e sarà restituito 1.

La volta successiva che la funzione callback viene eseguita, accumulator + number sarà 1 + 2 = 3 (1 è il valore precedentemente restituito nell'iterazione precedente e 2 è l'elemento successivo nell'array).

Poi, la volta successiva che viene eseguita la funzione callback, accumulator + number sarà 3 + 3 = 6 (il primo 3 è il valore precedentemente restituito nell'iterazione precedente e il secondo 3 è l'elemento successivo nell'array) e continuerà finché tutti gli elementi nell'array numbers non saranno iterati.

Quindi accumulator conterrà il valore dell'ultima operazione proprio come una variabile statica.

Nel codice qui sopra, il valore iniziale di 0 non è richiesto perché tutti gli elementi dell'array sono interi.

Quindi anche il codice qui sotto funzionerà:

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

const sum = numbers.reduce(function (accumulator, number) {
  return accumulator + number;
});

console.log(sum); // 15

Ecco una demo su Code Pen.

accumulator conterrà il primo elemento dell'array e number conterrà l'elemento successivo ( 1 + 2 = 3 durante la prima iterazione e poi 3 + 3 = 6 durante la successiva e così via).

Ma è sempre bene specificare il valore iniziale di accumulator dato che rende semplice capire il tipo del valore di ritorno del metodo reduce restituendo il tipo di dato corretto.

Dai un'occhiata al codice qui sotto:

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

const doublesSum = numbers.reduce(function (accumulator, number) {
  return accumulator + number * 2;
}, 10);

console.log(doublesSum); // 40

Ecco una demo su Code Pen.

Abbiamo moltiplicato ogni elemento dell'array per 2. Abbiamo fornito il valore iniziale di 10 per accumulator quindi 10 sarà aggiunto al risultato finale della somma in questo modo:

[1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2] = [2, 4, 6, 8, 10] = 30 + 10 = 40

Immagina di avere un array di oggetti con coordinate x e y e di voler ottenere la somma delle coordinate x. Per questo puoi usare il metodo reduce.

const coordinates = [
  { x: 1, y: 2 }, 
  { x: 2, y: 3 }, 
  { x: 3, y: 4 }
];

const sum = coordinates.reduce(function (accumulator, currentValue) {
    return accumulator + currentValue.x;
}, 0);

console.log(sum); // 6

Ecco una demo su Code Pen.

Vantaggi dell'uso del metodo reduce

  • Usare reduce consente di generare qualsiasi tipo di dato semplice o complesso per un array
  • Ricorda i dati restituiti precedentemente dal loop, quindi evita la creazione di una variabile globale per memorizzare il valore precedente

Supporto browser

  • Tutti i browser moderni e Internet Explorer (IE) versione 9 e successive
  • Microsoft Edge versione 12 e successive

Grazie per aver letto questo articolo!

Vuoi imparare tutte le funzionalità di ES6+ nel dettaglio, compresi let e const, promise, metodi per promise, destrutturazioni di array e oggetti, funzioni freccia, async/await, import, export e tanto altro?

Ti consiglio il mio libro Mastering Modern JavaScript (risorsa in inglese). Questo libro tratta tutti i prerequisiti per imparare React e ti aiuterà a migliorare con JavaScript e React.

Dai anche un'occhiata al mio corso gratuito Introduction to React Router (risorsa in inglese) per imparare a usare React Router da zero.

Vuoi restare aggiornato sui contenuti di JavaScript, React, Node.js? Seguimi su LinkedIn.