Ilreduce()
metodo su array JavaScript esegue una funzione “reducer” su ogni elemento della matrice in ordine, passando il valore di ritorno dalla precedente reducercall alla successiva chiamata reducer. La funzionereduce()
è una causa comune di confusione, ma può anche rendere il codice molto più leggibile se combinato con altre astrazioni di programmazione funzionale.,Ecco 4 esempi comuni e 1 esempio non così comune che dimostrano come usare reduce()
.
Sommando una matrice di numeri
La maggior partereduce()
i tutorial iniziano con questo esempio: dato un array di numeri, calcola la somma. Ecco come si potrebbe riassumere un array con un normale ciclo
for
.,
function sum(arr) { let sum = 0; for (const val of arr) { sum += val; } return sum;}sum(); // 16
Ecco un esempio equivalente utilizzando reduce()
:
function sum(arr) { const reducer = (sum, val) => sum + val; const initialValue = 0; return arr.reduce(reducer, initialValue);}sum(); // 16
reduce()
funzione di 2 parametri sono funzione reducer()
andan arbitrario initialValue
. JavaScript chiama quindireducer()
su ciascun elemento dell’array con il valore dell’accumulatore come primo parametro.L’accumulatore inizia come initialValue
, quindi JavaScript utilizza il valore di ritorno di ogni chiamata reduce()
come nuovo accumulatore.,
Parlare è economico, mostrami il codice. Quindi ecco un rapido esempio di come si potrebbe implementare una funzione reduce()
semplificata utilizzando for
loop.
Sommando una matrice di proprietà numeriche
La funzionereduce()
di per sé è spesso più confusa che utile.Se tutto ciò che devi fare è sommare una matrice di numeri, potresti essere meglio usando un ciclo for
., Ma, quando combinato con altri metodi di array comefilter()
e map()
,reduce()
inizia a sembrare più attraente.
Ad esempio, supponiamo di avere una matrice di elementi pubblicitari e di voler calcolarela somma della proprietàtotal
di ogni elemento pubblicitario.
Ecco un modo per aggiungere le voci total
usandoreduce()
:
lineItems.reduce((sum, li) => sum + li.total, 0); // 17.5
Questo funziona, ma è meno componibile. Un’alternativa migliore è prima map()
per otteneretotal
.,
lineItems.map(li => li.total).reduce((sum, val) => sum + val, 0);
Perché questo secondo approccio è migliore? Perché puoi astrarre thereducer in una funzionesum()
e riutilizzarlo ovunque sia necessario sommare un array.
Questo è importante perché, mentre pensi chesumReducer()
non cambierà mai, lo farà. Ad esempio, il codice precedente non tiene conto del fatto che0.1 + 0.2 !== 0.3
in JavaScript. Questo è un errore comune quando si calcolaprezzi in un linguaggio interpretato. I punti mobili binari sono strani.,Quindi è effettivamente necessario arrotondare:
const { round } = require('lodash');function sumReducer(sum, val) { // Round to 2 decimal places. return _.round(sum + val, 2);}
reduce()
rende facile riutilizzare la logica come sumReducer()
durante il concatenamento delle funzioni di appusing. Quindi puoi cambiare la tua logica una volta piuttosto che cercare ogni ciclo for
nella tua app.
Trova il valore massimo
Ad esempio, supponiamo di avere una serie di date JavaScript e di volereper trovare la data più recente.
const dates = .map(v => new Date(v));
Un approccio consiste nell’ordinare l’array e prendere l’ultimo elemento in sortedarray., Funziona, ma non è così efficiente come potrebbe essere, e l’ordinamento di una serie di date in JavaScript non è banale.
Invece, puoi usare reduce()
e fare in modo che il tuo riduttore restituisca la data più recente trovata finora.
Valori di raggruppamento
Dato un array di oggetti con unage
proprietà:
const characters = ;
Come si restituisce una mappa che contiene quanti caratteri hanno un datoage
? Ad esempio, l’output corretto sull’array precedente sarebbe{ 29: 2, 59: 1 }
.,
Ecco come puoi farlo con reduce()
.
Bonus: Prometti il concatenamento
Supponiamo di avere una serie di funzioni asincrone che vuoi eseguire in serie.Esiste una funzione non standard promise.series
per questo, ma puoi farlo anche con reduce()
.
In movimento su
Ilreduce()
funzione è un potente strumento. Astraendo filtri e riduttori, è possibile consolidare attività comuni come “sommare una serie di numeri”in una funzione separata per facilitare il refactoring e il codice di DRY-er.