Array come Stack e Code in JavaScript

Concetti Chiave
  • In JavaScript, gli array possono essere utilizzati come stack e code grazie ai metodi push(), pop(), shift() e unshift().
  • I metodi push() e pop() consentono di lavorare con gli array come stack, seguendo il principio LIFO (Last In, First Out).
  • Il metodo push() aggiunge uno o più nuovi elementi alla fine di un array, mentre pop() rimuove l'ultimo elemento dell'array e restituisce il valore rimosso.
  • I metodi unshift() e shift() consentono di lavorare con gli array come code, seguendo il principio FIFO (First In, First Out).
  • unshift() aggiunge uno o più nuovi elementi all'inizio di un array, mentre shift() rimuove il primo elemento dell'array e restituisce il valore rimosso.
  • Gli array in JavaScript possono essere utilizzati per implementare stack e code, ma è importante considerare l'efficienza delle operazioni, poiché unshift() e shift() possono essere meno efficienti rispetto a push() e pop().

Usare Array come Stack e Code

Uno dei grandi vantaggi degli array in JavaScript è che possono essere utilizzati come stack e code, grazie ai metodi push(), pop(), shift() e unshift().

I metodi push() e pop() consentono di lavorare con gli array come se fossero stack.

Il metodo push() aggiunge uno o più nuovi elementi alla fine di un array e restituisce la nuova lunghezza dell'array. A differenza di concat(), push() non appiattisce gli argomenti array. Il metodo pop() fa l'opposto: elimina l'ultimo elemento di un array, decrementa la lunghezza dell'array, e restituisce il valore che ha rimosso.

Si noti che entrambi i metodi modificano l'array sul posto. La combinazione di push() e pop() consente di utilizzare un array JavaScript per implementare uno stack, ossia una pila, una struttura dati in cui gli elementi vengono aggiunti e rimossi solo dalla fine, seguendo il principio LIFO (Last In, First Out).

Vediamo un esempio:

// Iniziamo con un array vuoto.
// Rappresenta una pila vuota.
let pila = [];       // pila == []

// Aggiungiamo due elementi alla pila.
// La pila ora contiene due elementi.
pila.push(1,2);      // pila == [1,2];

// Rimuoviamo l'ultimo elemento dalla pila.
pila.pop();          // pila == [1]; restituisce 2

// Aggiungiamo un altro elemento alla pila.
// La pila ora contiene due elementi.
pila.push(3);        // pila == [1,3]

// Rimuoviamo l'ultimo elemento dalla pila.
pila.pop();          // pila == [1]; restituisce 3

// Aggiungiamo un array alla pila.
pila.push([4,5]);    // pila == [1,[4,5]]

// Rimuoviamo l'ultimo elemento dalla pila.
pila.pop()           // pila == [1]; restituisce [4,5]

// Rimuoviamo l'ultimo elemento dalla pila.
// La pila ora è vuota.
pila.pop();          // pila == []; restituisce 1

Il metodo push() non appiattisce l'array passato, ma se vogliamo inserire tutti gli elementi da un array su un altro array, possiamo utilizzare l'operatore spread per appiattirlo esplicitamente:

let valori = [4,5];

// Aggiungiamo gli elementi dell'array `valori`
// all'array a
a.push(...valori);

I metodi unshift() e shift() si comportano molto come push() e pop(), eccetto che inseriscono e rimuovono elementi dall'inizio di un array piuttosto che dalla fine. unshift() aggiunge un elemento o elementi all'inizio dell'array, sposta gli elementi dell'array esistenti verso indici più alti per fare spazio, e restituisce la nuova lunghezza dell'array. shift() rimuove e restituisce il primo elemento dell'array, spostando tutti gli elementi successivi giù di una posizione per occupare lo spazio appena liberato all'inizio dell'array.

Si potrebbe utilizzare unshift() e shift() per implementare uno stack, ma sarebbe meno efficiente che utilizzare push() e pop() perché gli elementi dell'array devono essere spostati su o giù ogni volta che un elemento viene aggiunto o rimosso all'inizio dell'array.

Invece, si potrebbe implementare una struttura dati coda utilizzando push() per aggiungere elementi alla fine di un array e shift() per rimuoverli dall'inizio dell'array:

// Iniziamo con una coda vuota.
let q = [];            // q == []

// Aggiungiamo due elementi alla coda.
q.push(1,2);           // q == [1,2]

// Rimuoviamo il primo elemento dalla coda.
q.shift();             // q == [2]; restituisce 1

// Aggiungiamo un altro elemento alla coda.
q.push(3)              // q == [2, 3]

// Rimuoviamo il primo elemento dalla coda.
q.shift()              // q == [3]; restituisce 2

// Rimuoviamo un altro elemento dalla coda.
// La coda ora è vuota.
q.shift()              // q == []; restituisce 3

C'è una caratteristica di unshift() che vale la pena evidenziare perché potrebbe sorprendere alcuni lettori. Quando passiamo più argomenti a unshift(), essi vengono inseriti tutti in una volta, il che significa che finiscono nell'array in un ordine diverso rispetto a se li inserissimo uno alla volta:

let a = [];            // a == []
a.unshift(1)           // a == [1]
a.unshift(2)           // a == [2, 1]
a = [];                // a == []
a.unshift(1,2)         // a == [1, 2]

La motivazione di questo comportamento è che unshift() inserisce gli elementi nell'array in base all'ordine in cui vengono forniti, piuttosto che all'ordine in cui vengono chiamati. Quindi, se passiamo più argomenti a unshift(), tutti gli argomenti vengono inseriti all'inizio dell'array in un'unica operazione, piuttosto che uno alla volta.