Etienne Talbot

Seguire

Jan 29, 2018 · 7 min leggere

Se si sta iniziando in JavaScript, forse non avete sentito parlare di .map() .reduce() e .filter()., Per me, ci è voluto un po ‘ perché ho dovuto supportare Internet Explorer 8 fino a un paio di anni fa. Ma se non è necessario essere compatibili con questo browser molto vecchio, è necessario acquisire familiarità con questi metodi.

Prendi nota che questo articolo si applica molto probabilmente a qualsiasi altro linguaggio di programmazione che potresti usare, poiché questi sono concetti che esistono in molte altre lingue.

Lasciatemi spiegare come funziona con un semplice esempio. Supponiamo di aver ricevuto un array contenente più oggetti, ognuno dei quali rappresenta una persona., La cosa di cui hai veramente bisogno alla fine, però, è un array contenente solo l’ID di ogni persona.

Confrontiamo!

Utilizzando.forEach():

var officersIds = ;officers.forEach(function (officer) {
officersIds.push(officer.id);
});

Si noti come è necessario creare un array vuoto in anticipo? Vediamo come appare quando si utilizza .map():

var officersIds = officers.map(function (officer) {
return officer.id
});

Possiamo anche essere più concisi con le funzioni arrow (richiede il supporto ES6, Babel o TypeScript)

const officersIds = officers.map(officer => officer.id);

Quindi come funziona .map() lavoro?, Fondamentalmente è prende 2 argomenti, un callback e un contesto opzionale (sarà considerato come this nel callback) che non ho usato nell’esempio precedente. Il callback viene eseguito per ogni valore nell’array e restituisce ogni nuovo valore nell’array risultante.

Tieni presente che l’array risultante avrà sempre la stessa lunghezza dell’array originale.

.reduce()

Proprio come .map(), .reduce() esegue anche un callback per ogni elemento di un array., Ciò che è diverso qui è che reduce passa il risultato di questo callback (l’accumulatore) da un elemento dell’array all’altro.

L’accumulatore può essere praticamente qualsiasi cosa (intero, stringa, oggetto, ecc.) e deve essere istanziato o passato quando si chiama .reduce().

Tempo per un esempio! Supponiamo che tu abbia un array con questi piloti e i loro rispettivi anni di esperienza:

Abbiamo bisogno di conoscere gli anni totali di esperienza di tutti loro., Con .reduce(), è piuttosto semplice:

var totalYears = pilots.reduce(function (accumulator, pilot) {
return accumulator + pilot.years;
}, 0);

Si noti che ho impostato il valore iniziale come 0. Avrei potuto anche usare una variabile esistente se necessario. Dopo aver eseguito il callback per ogni elemento dell’array, reduce restituirà il valore finale del nostro accumulatore (nel nostro caso: 82).

Vediamo come questo può essere abbreviato con le funzioni freccia di ES6:

const totalYears = pilots.reduce((acc, pilot) => acc + pilot.years, 0);

Ora diciamo che voglio trovare quale pilota è il più esperto., Per questo, posso usare anche reduce:

var mostExpPilot = pilots.reduce(function (oldest, pilot) {
return (oldest.years || 0) > pilot.years ? oldest : pilot;
}, {});

Ho chiamato il mio accumulatore oldest. Il mio callback confronta l’accumulatore con ogni pilota. Se un pilota ha più anni di esperienza di oldest, allora quel pilota diventa il nuovo oldest quindi è quello che ritorno.

Come puoi vedere, usare .reduce() è un modo semplice per generare un singolo valore o oggetto da un array.

.filter ()

Cosa succede se si dispone di un array, ma si desidera solo alcuni degli elementi in esso contenuti?, Ecco dove entra .filter()!

Ecco i nostri dati:

Diciamo che vogliamo due array ora: uno per i piloti ribelli, l’altro per gli imperiali. Con .filter() non potrebbe essere più facile!

Questo è tutto! Ed è ancora più breve con le funzioni freccia:

const rebels = pilots.filter(pilot => pilot.faction === "Rebels");
const empire = pilots.filter(pilot => pilot.faction === "Empire");

Fondamentalmente, se la funzione di callback restituisce true, l’elemento corrente sarà nell’array risultante. Se restituisce false, non lo sarà.

Combinazione .mappa(), .ridurre (), e .,filter()

Poiché tutti e tre sono chiamati su array e poiché .map() e .filter() entrambi gli array di ritorno, possiamo facilmente concatenare le nostre chiamate.

Diamo un’occhiata a un altro esempio. Ecco i nostri dati:

Il nostro obiettivo: ottenere il punteggio totale degli utenti di forza solo. Facciamolo passo dopo passo!

Per prima cosa, dobbiamo filtrare il personale che non può usare la forza:

var jediPersonnel = personnel.filter(function (person) {
return person.isForceUser;
});// Result: (Luke, Ezra and Caleb)

Con questo abbiamo 3 elementi rimasti nel nostro array risultante. Ora dobbiamo creare un array contenente il punteggio totale di ogni Jedi.,

var jediScores = jediPersonnel.map(function (jedi) {
return jedi.pilotingScore + jedi.shootingScore;
});// Result:

E usiamo reduce per ottenere il totale:

var totalJediScore = jediScores.reduce(function (acc, score) {
return acc + score;
}, 0);// Result: 420

E ora ecco la parte divertente can possiamo concatenare tutto questo per ottenere ciò che vogliamo in una singola riga:

E guarda quanto è bello con le funzioni freccia:

Boom! Note

Nota: nel mio esempio precedente, .map()e.filter() non erano nemmeno necessari. Potremmo facilmente ottenere lo stesso risultato con solo .reduce(). Li ho lasciati lì per il bene di questo esempio., Riesci a indovinare come potremmo mantenere solo .reduce() e ottenere lo stesso risultato con una riga di codice? Vedi la soluzione su CodePen

Perché non usare .forEach ()?

Ho usatoforloop ovunque invece di.map(),.reduce()e.filter(). Ma un paio di anni fa ho iniziato a lavorare molto di più con i dati provenienti da un’API. È qui che ho iniziato a vedere i vantaggi di lasciare .forEach dietro.,

Formattazione

Dire che è necessario visualizzare un elenco di persone, con il loro nome e titolo di lavoro.

var data = 

L’API ti fornisce i dati di cui sopra, ma hai solo bisogno del titolo e del cognome di ogni persona… devi formattare i dati. Tuttavia, la tua app deve anche avere una singola vista per ogni persona, quindi devi scrivere una funzione di formattazione dei dati che funzioni sia in una vista elenco che in una singola vista.,

il che significa Che si può avere un .forEach loop all’interno della funzione di formattazione, altrimenti si dovrebbe avvolgere il singolo elemento in un array prima di passare alla funzione per farlo funzionare, in questo modo:

var result = formatElement();
// Yeah... that's not right at all

il ciclo è quello di avvolgere la chiamata della funzione, come questo:

data.forEach(function (element) {
var formatted = formatElement(element);
// But what then....
});

Ma .forEach() non restituisce nulla. Ciò significa che devi spingere i risultati all’interno di un array predeterminato.,

var results = ;data.forEach(function (element) {
var formatted = formatElement(element);
results.push(formatted);
});

Di conseguenza, hai 2 funzioni: la tua funzioneformatElement() e la tua funzione che spinge i risultati nel tuo array.

Perché avere 2 funzioni quando puoi averne solo una?

var results = data.map(formatElement);

Il test è più semplice

Se scrivi test unitari per il tuo codice, troverai più semplice testare le funzioni che chiami con .map(), .reduce(), o .filter().

Tutto ciò che devi fare è fornire dati in entrata per la funzione e aspettarti che venga fuori un risultato., Fondamentalmente ” cosa viene fuori se questo è passato?”. Meno manipolazione ,meno beforeEach()s eafterEach() s. È un test semplice e semplice.

Provalo!

Se ti è piaciuto questo articolo e vuoi saperne di più metodi di array, controlla il mio articolo su come usare .some()e .find() in JavaScript.

Continua a codificare!

Articles

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *