Array in JavaScript: strutture FIFO, LIFO e iterazioni per gestire collezioni operative

by Anastasia P.
SHARE
Array in JavaScript: strutture FIFO, LIFO e iterazioni per gestire collezioni operative
© Guida-HTML5.it

Introduzione

Gli array di JavaScript non servono soltanto a conservare una lista di valori. Grazie ai loro metodi, possono rappresentare strutture operative molto utili, come una coda FIFO e una pila LIFO. Queste due strategie sono presenti in moltissimi programmi reali: una coda di richieste da elaborare, una lista di attività in attesa, la cronologia delle azioni dell’utente o una serie di notifiche da mostrare.

FIFO significa First In, First Out: il primo elemento inserito è il primo a essere rimosso. È il comportamento tipico di una coda, simile alla fila davanti a uno sportello. LIFO significa invece Last In, First Out: l’ultimo elemento inserito è il primo a essere rimosso. È il comportamento di una pila, come una serie di piatti impilati.

In questo tutorial costruiremo una piccola coda di attività e una pila per la cronologia delle azioni. Useremo la creazione degli array, i metodi push, pop, shift e unshift, oltre a iterazioni con for...of e forEach. L’obiettivo è capire non solo come funzionano questi metodi, ma anche quando è opportuno utilizzarli.

Codice completo

const codaAttivita = [];
const cronologiaAzioni = [];

// Aggiunge attività in fondo alla coda: comportamento FIFO
codaAttivita.push("Inviare il report");
codaAttivita.push("Controllare le email");
codaAttivita.push("Aggiornare il calendario");

// Aggiunge un´azione alla pila: comportamento LIFO
cronologiaAzioni.push("Aperta la pagina delle impostazioni");
cronologiaAzioni.push("Modificato il tema");
cronologiaAzioni.push("Salvate le preferenze");

function mostraCoda(coda) {
  console.log("Attività in attesa:");

  for (const attivita of coda) {
    console.log(`- ${attivita}`);
  }
}

function eseguiProssimaAttivita(coda) {
  if (coda.length === 0) {
    return null;
  }

  // shift rimuove e restituisce il primo elemento
  return coda.shift();
}

function annullaUltimaAzione(pila) {
  if (pila.length === 0) {
    return null;
  }

  // pop rimuove e restituisce l´ultimo elemento
  return pila.pop();
}

mostraCoda(codaAttivita);

const attivitaEseguita = eseguiProssimaAttivita(codaAttivita);
console.log(`Attività eseguita: ${attivitaEseguita}`);

const azioneAnnullata = annullaUltimaAzione(cronologiaAzioni);
console.log(`Azione annullata: ${azioneAnnullata}`);

console.log("Coda aggiornata:");
codaAttivita.forEach((attivita, indice) => {
  console.log(`${indice + 1}. ${attivita}`);
});

console.log("Cronologia rimasta:");
for (const azione of cronologiaAzioni) {
  console.log(`- ${azione}`);
}

Spiegazione

Creare e inizializzare un array

Un array vuoto si crea con la sintassi []:

const coda = [];

La parola chiave const impedisce di riassegnare la variabile a un altro array, ma non impedisce di modificare il contenuto dell’array. Per esempio, questa operazione è valida:

const numeri = [];
numeri.push(10);

console.log(numeri); // [10]

Non sarebbe invece possibile sostituire completamente il riferimento:

const numeri = [];
// numeri = [10, 20]; // Errore: assegnazione non consentita

Se conosci già gli elementi iniziali, puoi usare un array letterale:

const priorita = ["alta", "media", "bassa"];

Gestire una pila con push e pop

Una pila LIFO usa normalmente push per aggiungere elementi in fondo e pop per rimuovere l’ultimo elemento.

const pila = [];

pila.push("A");
pila.push("B");
pila.push("C");

console.log(pila.pop()); // C
console.log(pila.pop()); // B
console.log(pila);       // ["A"]

pop modifica l’array originale e restituisce l’elemento eliminato. Se la pila è vuota, restituisce undefined. Per questo è buona pratica controllare la proprietà length prima di utilizzare il risultato, soprattutto quando l’operazione rappresenta un’azione importante.

Gestire una coda con push e shift

Una coda FIFO inserisce gli elementi in fondo con push e rimuove il primo elemento con shift:

const coda = ["Primo", "Secondo", "Terzo"];

const elemento = coda.shift();

console.log(elemento); // Primo
console.log(coda);     // ["Secondo", "Terzo"]

Il metodo unshift svolge l’operazione opposta a shift: inserisce uno o più elementi all’inizio dell’array.

const messaggi = ["Messaggio normale"];

messaggi.unshift("Messaggio urgente");

console.log(messaggi);
// ["Messaggio urgente", "Messaggio normale"]

In questo modo è possibile dare priorità a un elemento. Tuttavia, shift e unshift possono essere meno efficienti su array molto grandi, perché gli altri elementi devono essere spostati internamente. Per piccole collezioni sono semplici e adatti; per code molto grandi o ad alta frequenza è preferibile valutare una struttura con indice di lettura.

Iterare gli elementi della struttura

Il ciclo for...of è utile quando vuoi leggere ogni valore in modo diretto:

for (const elemento of coda) {
  console.log(elemento);
}

Il metodo forEach è una soluzione compatta quando vuoi eseguire una funzione per ogni elemento:

coda.forEach((elemento, indice) => {
  console.log(`${indice}: ${elemento}`);
});

Se devi interrompere l’iterazione prima della fine, forEach non è la scelta migliore, perché non supporta direttamente break. In questi casi è preferibile usare for...of:

for (const attivita of coda) {
  if (attivita === "Controllare le email") {
    break;
  }

  console.log(attivita);
}

Controllare se una coda è vuota

La proprietà length permette di sapere quanti elementi sono presenti. Un array vuoto ha lunghezza pari a zero:

if (coda.length === 0) {
  console.log("Nessuna attività da eseguire");
} else {
  console.log(`Attività presenti: ${coda.length}`);
}

Questo controllo è importante prima di chiamare shift o pop, soprattutto all’interno di funzioni riutilizzabili.

Best practice

  • Dai nomi espliciti agli array: nomi come codaAttivita o cronologiaAzioni rendono chiaro il ruolo della collezione.
  • Incapsula le operazioni: funzioni come eseguiProssimaAttivita e annullaUltimaAzione evitano di duplicare controlli e regole nel codice.
  • Controlla gli array vuoti: shift e pop restituiscono undefined quando non ci sono elementi.
  • Scegli l’iterazione corretta: usa for...of quando ti serve interrompere il ciclo o usare await in contesti appropriati; usa forEach per semplici visite complete.
  • Considera le prestazioni: su array molto grandi, rimuovere continuamente il primo elemento con shift può essere costoso.
  • Non confondere indice e valore: for...of restituisce direttamente i valori, mentre un ciclo tradizionale usa gli indici.

Per simulare una coda più efficiente, puoi usare un indice che indica il prossimo elemento da elaborare:

const richieste = ["R1", "R2", "R3"];
let indiceLettura = 0;

function prossimaRichiesta() {
  if (indiceLettura >= richieste.length) {
    return null;
  }

  const richiesta = richieste[indiceLettura];
  indiceLettura++;
  return richiesta;
}

console.log(prossimaRichiesta()); // R1
console.log(prossimaRichiesta()); // R2

Questa tecnica evita di spostare tutti gli elementi a ogni rimozione. Quando l’indice cresce molto, puoi eventualmente ricostruire l’array per liberare lo spazio già consumato.

Riepilogo

Gli array JavaScript possono essere usati come strutture dati operative, non solo come contenitori di valori. Con push e pop puoi implementare una pila LIFO, ideale per cronologie e operazioni di annullamento. Con push e shift puoi invece creare una coda FIFO, utile per attività, richieste o messaggi da processare nell’ordine di arrivo.

Le iterazioni con for...of e forEach permettono di visualizzare o elaborare gli elementi, mentre length aiuta a gestire correttamente le collezioni vuote. La scelta dei metodi deve tenere conto sia della leggibilità sia delle prestazioni, soprattutto quando gli array diventano grandi.

Approfondisci con risorse ufficiali

SHARE