Introduzione
Un caso pratico in cui i cicli JavaScript sono particolarmente utili è l’elaborazione di dati provenienti da un file CSV. Un CSV, cioè Comma-Separated Values, contiene righe di testo in cui i valori sono separati da virgole. Questo formato viene spesso usato per esportare ordini, prodotti, utenti o risultati di analisi.
In questo tutorial costruiremo uno script che legge un piccolo CSV, analizza ogni riga, calcola il totale degli ordini e produce un report finale. Useremo i tre cicli fondamentali:
- for per attraversare un insieme di righe;
- while per leggere i caratteri di una riga fino alla fine;
- do...while per mostrare almeno una volta un messaggio di riepilogo.
L’esempio è volutamente realizzato senza librerie esterne, così da capire come funzionano realmente le iterazioni. In un progetto professionale sarà comunque importante gestire correttamente CSV complessi, contenenti virgolette, virgole nei testi e righe multilinea.
Codice completo
const csv = `prodotto,quantita,prezzo
Tastiera,2,49.90
Mouse,3,19.50
Monitor,1,189.99
Cuffie,4,32.75`;
const righe = csv.split("n");
// La prima riga contiene i nomi delle colonne.
const intestazioni = righe[0].split(",");
const ordini = [];
let totaleGenerale = 0;
// for: attraversiamo tutte le righe dei dati.
for (let i = 1; i < righe.length; i++) {
const riga = righe[i].trim();
// Ignoriamo eventuali righe vuote.
if (riga === "") {
continue;
}
const valori = riga.split(",");
const prodotto = valori[0];
const quantita = Number(valori[1]);
const prezzo = Number(valori[2]);
if (Number.isNaN(quantita) || Number.isNaN(prezzo)) {
console.warn(`Riga non valida: ${riga}`);
continue;
}
const totaleRiga = quantita * prezzo;
ordini.push({
prodotto,
quantita,
prezzo,
totale: totaleRiga
});
totaleGenerale += totaleRiga;
}
// while: analizziamo una riga costruendo manualmente i campi.
// Questo esempio mostra come avanzare con un indice.
let indice = 0;
let caratteriPrimaRiga = 0;
while (indice < righe[1].length) {
caratteriPrimaRiga++;
indice++;
}
console.log(`Caratteri della prima riga dati: ${caratteriPrimaRiga}`);
// do...while: il riepilogo viene mostrato almeno una volta.
let mostraRiepilogo = true;
do {
console.log("=== REPORT ORDINI ===");
for (let i = 0; i < ordini.length; i++) {
const ordine = ordini[i];
console.log(
`${ordine.prodotto}: ${ordine.quantita} x ` +
`${ordine.prezzo.toFixed(2)} € = ` +
`${ordine.totale.toFixed(2)} €`
);
}
console.log(`Totale generale: ${totaleGenerale.toFixed(2)} €`);
// In questo esempio il report viene stampato una sola volta.
mostraRiepilogo = false;
} while (mostraRiepilogo); Spiegazione
Separare il contenuto in righe
Il metodo split("n") divide la stringa CSV ogni volta che incontra un ritorno a capo. Il risultato è un array: il primo elemento contiene l’intestazione, mentre gli elementi successivi contengono i dati degli ordini.
Per questo motivo il ciclo for inizia da i = 1 invece che da zero. La condizione i < righe.length impedisce di accedere a una posizione inesistente. A ogni iterazione, l’espressione i++ incrementa l’indice e permette al ciclo di passare alla riga successiva.
Perché usare for per le righe
Il ciclo for è adatto quando conosciamo l’array da attraversare e vogliamo controllare esplicitamente l’indice. In questo esempio ci serve perché dobbiamo saltare la prima riga, quella delle intestazioni.
L’istruzione continue permette di ignorare una riga vuota o non valida senza interrompere tutto il ciclo. È una tecnica utile quando un singolo elemento non deve bloccare l’elaborazione degli altri dati.
Come funziona il while
Il ciclo while continua finché la sua condizione è vera. Nell’esempio, l’indice viene incrementato finché non raggiunge la lunghezza della prima riga. È fondamentale modificare la variabile usata nella condizione, altrimenti si rischia un ciclo infinito.
In un parser più avanzato, un while potrebbe leggere un carattere alla volta e riconoscere separatori, virgolette e valori protetti. Questa tecnica è utile quando il semplice split(",") non è sufficiente.
Quando preferire do...while
Il ciclo do...while esegue il blocco almeno una volta e controlla la condizione soltanto alla fine. Qui viene usato per simulare un report che deve essere visualizzato almeno una volta, anche se in seguito potrebbe essere deciso di non ripeterlo.
La differenza principale rispetto a while è quindi il momento in cui viene verificata la condizione. Con while il blocco potrebbe non essere mai eseguito; con do...while viene sempre eseguito almeno una volta.
Calcolo dei totali
Le quantità e i prezzi arrivano dal CSV come stringhe. Per eseguire operazioni matematiche vengono convertiti con Number(). Il controllo con Number.isNaN() evita di inserire nel report valori che non possono essere interpretati come numeri.
Il totale della riga è ottenuto moltiplicando quantità e prezzo. La variabile totaleGenerale accumula progressivamente tutti i subtotali. Il metodo toFixed(2) formatta il risultato con due cifre decimali.
Best practice
- Inizializza correttamente gli indici: scegli il valore iniziale in base al contenuto dell’array e non dare per scontato che la prima posizione contenga dati.
- Evita i cicli infiniti: in un
whileo in undo...while, aggiorna sempre la variabile presente nella condizione. - Valida i dati esterni: file e input possono contenere righe vuote, valori mancanti o numeri non validi.
- Usa nomi descrittivi: variabili come
totaleGenerale,righeeindicerendono il codice più leggibile. - Non confondere formato e logica: il calcolo dei totali dovrebbe restare separato dalla stampa del report.
- Considera i casi reali: un CSV professionale può contenere virgole dentro un campo, virgolette e righe con terminatori diversi, come
rn. - Limita il lavoro nel ciclo: calcoli ripetuti e inutili dentro molte iterazioni possono rallentare l’applicazione.
Riepilogo
I cicli permettono di trasformare dati grezzi in informazioni utili. Nel nostro esempio, for ha attraversato le righe del CSV, while ha contato i caratteri di una riga e do...while ha gestito un’operazione che doveva essere eseguita almeno una volta.
La scelta del ciclo dipende dal problema: usa for quando lavori con una sequenza indicizzata, while quando la ripetizione dipende da una condizione verificata prima e do...while quando il blocco deve essere eseguito almeno una volta.
