Introduzione
Le funzioni di ordine superiore map, filter e reduce sono tra gli strumenti più utili in JavaScript quando si lavora con array di dati. Invece di scrivere cicli lunghi e pieni di variabili temporanee, queste funzioni permettono di esprimere in modo chiaro come trasformare, selezionare e aggregare le informazioni.
In questo tutorial vediamo un caso pratico e molto comune: preparare i dati di una dashboard. Immagina di ricevere una lista di ordini da un e-commerce. Prima di mostrarli a schermo, vuoi:
- filtrare gli ordini completati;
- trasformare i dati in un formato più leggibile;
- calcolare il totale incassato;
- raggruppare gli ordini per categoria.
Questo è un scenario perfetto per combinare filter, map e reduce in modo pulito e professionale.
Codice completo
// Dati di esempio: ordini ricevuti da un e-commerce
const orders = [
{ id: 1, customer: "Luca", category: "books", amount: 24.90, status: "completed" },
{ id: 2, customer: "Anna", category: "electronics", amount: 199.99, status: "pending" },
{ id: 3, customer: "Marco", category: "books", amount: 15.50, status: "completed" },
{ id: 4, customer: "Giulia", category: "home", amount: 89.00, status: "completed" },
{ id: 5, customer: "Sara", category: "electronics", amount: 349.00, status: "completed" },
{ id: 6, customer: "Paolo", category: "home", amount: 42.30, status: "cancelled" }
];
// 1) Selezioniamo solo gli ordini completati
const completedOrders = orders.filter(order => order.status === "completed");
// 2) Trasformiamo i dati in un formato più utile per la UI
const formattedOrders = completedOrders.map(order => ({
id: order.id,
customer: order.customer,
category: order.category,
amount: order.amount.toFixed(2),
label: `${order.customer} - ${order.category}`
}));
// 3) Calcoliamo il totale incassato dagli ordini completati
const totalRevenue = completedOrders.reduce((sum, order) => {
return sum + order.amount;
}, 0);
// 4) Raggruppiamo gli ordini completati per categoria
const revenueByCategory = completedOrders.reduce((acc, order) => {
if (!acc[order.category]) {
acc[order.category] = 0;
}
acc[order.category] += order.amount;
return acc;
}, {});
// 5) Prepariamo una stringa leggibile per il log
const summary = `
Ordini completati: ${completedOrders.length}
Ricavo totale: €${totalRevenue.toFixed(2)}
`;
console.log("Ordini formattati:", formattedOrders);
console.log("Ricavo per categoria:", revenueByCategory);
console.log(summary);
// Esempio di rendering semplice in pagina
const dashboardData = formattedOrders.map(order => `
<li>#${order.id} - ${order.label} - €${order.amount}</li>
`).join("");
document.body.innerHTML = `
<h2>Dashboard ordini</h2>
<ul>${dashboardData}</ul>
<p><strong>Ricavo totale:</strong> €${totalRevenue.toFixed(2)}</p>
`; Spiegazione
1. filter: selezionare solo ciò che serve
filter restituisce un nuovo array contenente solo gli elementi che rispettano una certa condizione. Nel nostro esempio usiamo:
const completedOrders = orders.filter(order => order.status === "completed"); Qui teniamo solo gli ordini con stato completed. Il vantaggio è evidente: tutte le elaborazioni successive lavorano su un dataset già pulito, senza dover ripetere il controllo ogni volta.
2. map: trasformare i dati
map serve a convertire ogni elemento dell’array in una nuova forma. Non modifica l’array originale, ma crea un nuovo array con valori trasformati.
const formattedOrders = completedOrders.map(order => ({
id: order.id,
customer: order.customer,
category: order.category,
amount: order.amount.toFixed(2),
label: `${order.customer} - ${order.category}`
})); In questo caso rendiamo i dati più adatti alla visualizzazione: formattiamo l’importo con due decimali e costruiamo una label leggibile per l’interfaccia utente.
3. reduce: aggregare e calcolare
reduce è la funzione più flessibile delle tre. Permette di accumulare un risultato finale a partire da tutti gli elementi dell’array.
Per calcolare il fatturato totale:
const totalRevenue = completedOrders.reduce((sum, order) => {
return sum + order.amount;
}, 0); Il valore iniziale 0 è importante: indica da dove parte l’accumulatore.
Un altro uso molto pratico di reduce è il raggruppamento. Nel nostro esempio costruiamo un oggetto con il totale per categoria:
const revenueByCategory = completedOrders.reduce((acc, order) => {
if (!acc[order.category]) {
acc[order.category] = 0;
}
acc[order.category] += order.amount;
return acc;
}, {}); Questo pattern è frequente in dashboard, report e analisi dati.
4. Combinare le funzioni in modo logico
La vera forza di queste funzioni emerge quando le combiniamo. Un flusso tipico potrebbe essere:
- filter per pulire i dati;
- map per adattarli alla presentazione;
- reduce per ottenere metriche e riepiloghi.
Questo approccio rende il codice più leggibile e facilita la manutenzione. Ogni passaggio ha una responsabilità precisa.
Best practice
- Non modificare l’array originale: map, filter e reduce sono più efficaci quando li usi in modo funzionale, senza side effect inutili.
- Usa nomi descrittivi: variabili come completedOrders o revenueByCategory spiegano subito il contenuto.
- Separa i passaggi complessi: una catena troppo lunga può diventare difficile da leggere. Meglio spezzare in variabili intermedie quando serve chiarezza.
- Ricorda il valore iniziale di reduce: senza un accumulatore iniziale corretto, il risultato può essere errato o generare bug.
- Evita logica troppo pesante dentro map: se la trasformazione diventa complessa, valuta di estrarre una funzione dedicata.
- Usa reduce solo quando serve davvero: per semplici somme o conteggi, va benissimo; per operazioni più leggibili con altri metodi, non forzarlo.
Riepilogo
In un contesto reale, come una dashboard dati, map, filter e reduce ti aiutano a scrivere codice più chiaro, modulare e vicino al problema che devi risolvere.
- filter seleziona gli elementi utili;
- map trasforma la struttura dei dati;
- reduce calcola valori aggregati o costruisce oggetti complessi.
Imparare a combinarle bene significa passare da un codice procedurale e dispersivo a uno più espressivo e professionale. È una competenza fondamentale per chi sviluppa interfacce, report, strumenti di analisi o applicazioni basate su dati.
Approfondisci con risorse ufficiali
- MDN - Array.prototype.map(): documentazione completa e esempi pratici.
- MDN - Array.prototype.filter(): guida ufficiale al filtraggio degli array.
- MDN - Array.prototype.reduce(): riferimento dettagliato sul metodo e sui casi d’uso.
- ECMAScript Specification: per chi vuole approfondire il comportamento standard dei metodi degli array.
Se vuoi fare un passo in più, prova a prendere un dataset reale, come una lista di prodotti, utenti o transazioni, e costruisci una mini-dashboard usando questi tre metodi. È il modo migliore per consolidare la teoria con un esercizio concreto.
