Set e Map in JavaScript moderno: gestire collezioni di dati in modo efficace

by Anastasia P.
SHARE
Set e Map in JavaScript moderno: gestire collezioni di dati in modo efficace
© Guida-HTML5.it

Introduzione

Tra le novità introdotte da ES6 ci sono due strutture dati molto utili: Set e Map. Prima di ES6, gli array e gli oggetti venivano spesso utilizzati per rappresentare qualunque tipo di collezione. Sebbene siano strumenti fondamentali, non sempre sono la scelta più adatta.

Un Set contiene valori unici: se proviamo ad aggiungere due volte lo stesso elemento, questo verrà memorizzato una sola volta. È quindi ideale per eliminare duplicati o verificare rapidamente la presenza di un valore.

Una Map contiene invece coppie formate da chiave e valore. A differenza degli oggetti tradizionali, una chiave di una Map può essere di qualunque tipo: stringa, numero, oggetto, funzione o persino un’altra struttura dati.

Queste collezioni fanno parte di JavaScript moderno e sono particolarmente utili quando si lavora con dati provenienti da API, filtri, cataloghi, cache e applicazioni interattive.

Codice completo

// Dati ricevuti da un sistema esterno.
// Alcuni tag sono ripetuti intenzionalmente.
const prodotti = [
  {
    id: 1,
    nome: "Tastiera",
    categoria: "accessori",
    prezzo: 49.90,
    tag: ["usb", "ufficio", "usb"]
  },
  {
    id: 2,
    nome: "Monitor",
    categoria: "display",
    prezzo: 199.90,
    tag: ["hdmi", "ufficio"]
  },
  {
    id: 3,
    nome: "Mouse",
    categoria: "accessori",
    prezzo: 24.90,
    tag: ["usb", "wireless"]
  }
];

// Set: otteniamo tutti i tag senza duplicati.
const tuttiITag = new Set();

prodotti.forEach((prodotto) => {
  prodotto.tag.forEach((tag) => {
    tuttiITag.add(tag);
  });
});

console.log("Tag disponibili:", [...tuttiITag]);

// Verifica rapida della presenza di un valore.
console.log("Esiste il tag wireless?", tuttiITag.has("wireless"));

// Map: indicizziamo i prodotti usando il loro id.
const prodottiPerId = new Map();

prodotti.forEach((prodotto) => {
  prodottiPerId.set(prodotto.id, prodotto);
});

// Recuperiamo un prodotto tramite la sua chiave.
const prodottoSelezionato = prodottiPerId.get(2);
console.log("Prodotto selezionato:", prodottoSelezionato.nome);

// Controlliamo se una chiave è presente.
console.log("Esiste il prodotto 10?", prodottiPerId.has(10));

// Calcoliamo il totale dei prodotti usando Map.values().
const totale = [...prodottiPerId.values()]
  .reduce((somma, prodotto) => somma + prodotto.prezzo, 0);

console.log("Totale catalogo:", totale.toFixed(2));

// Iteriamo su tutte le coppie chiave-valore.
prodottiPerId.forEach((prodotto, id) => {
  console.log(`${id}: ${prodotto.nome}`);
});

Spiegazione

Come funziona Set

Per creare un Set utilizziamo il costruttore new Set(). Possiamo anche inizializzarlo passando un iterable, ad esempio un array:

const numeri = new Set([1, 2, 2, 3, 3, 4]);

console.log(numeri);
// Set(4) { 1, 2, 3, 4 }

I metodi principali di Set sono:

  • add(valore): aggiunge un valore;
  • has(valore): restituisce true se il valore esiste;
  • delete(valore): rimuove un valore;
  • clear(): elimina tutti gli elementi;
  • size: indica il numero di elementi presenti.

Un caso molto comune consiste nel rimuovere i duplicati da un array. Poiché un Set accetta solo valori unici, basta convertirlo nuovamente in array:

const categorie = ["libri", "film", "libri", "musica"];

const categorieUniche = [...new Set(categorie)];

console.log(categorieUniche);
// ["libri", "film", "musica"]

È importante ricordare che Set considera distinti gli oggetti con riferimenti diversi, anche se hanno le stesse proprietà:

const primo = { id: 1 };
const secondo = { id: 1 };

const elementi = new Set([primo, secondo]);

console.log(elementi.size);
// 2, perché i due oggetti sono riferimenti differenti

Come funziona Map

Una Map associa ogni chiave a un valore. Per aggiungere dati si usa set(), mentre per recuperarli si utilizza get():

const utenti = new Map();

utenti.set("admin", {
  nome: "Giulia",
  ruolo: "amministratore"
});

utenti.set("editor", {
  nome: "Luca",
  ruolo: "redattore"
});

console.log(utenti.get("admin"));

I metodi e le proprietà più importanti sono:

  • set(chiave, valore): inserisce o aggiorna una coppia;
  • get(chiave): restituisce il valore associato;
  • has(chiave): verifica l’esistenza di una chiave;
  • delete(chiave): rimuove una coppia;
  • clear(): svuota la Map;
  • size: restituisce il numero di coppie.

Map mantiene l’ordine di inserimento degli elementi ed è particolarmente adatta per creare indici in memoria. Ad esempio, invece di cercare ogni volta un prodotto dentro un array con find(), possiamo indicizzarlo per ID e recuperarlo direttamente tramite get().

Conversione e iterazione

Set e Map sono strutture iterabili. Possiamo utilizzare for...of, il metodo forEach() oppure lo spread per convertirle in array:

const colori = new Set(["rosso", "verde", "blu"]);

for (const colore of colori) {
  console.log(colore);
}

const mappa = new Map([
  ["it", "Italiano"],
  ["en", "English"]
]);

for (const [codice, lingua] of mappa) {
  console.log(codice, lingua);
}

const arrayColori = [...colori];
const arrayCoppie = [...mappa];

Una Map può essere convertita in un array di chiavi, valori o coppie usando rispettivamente keys(), values() ed entries().

Best practice

  • Usa Set quando l’unicità è un requisito del dato, ad esempio per tag, permessi, codici o categorie.
  • Usa Map quando devi associare chiavi e valori o quando le chiavi non sono necessariamente stringhe.
  • Non usare Map automaticamente: per dati semplici e strutturati come un oggetto utente, un normale oggetto può essere più leggibile.
  • Evita di confondere Map con un oggetto: in una Map devi usare sempre i metodi set() e get(), non la sintassi con il punto.
  • Indicizza i dati frequentemente cercati: una Map può rendere il codice più chiaro e ridurre ricerche ripetute all’interno di array.
  • Converti in array solo quando serve: alcune operazioni come map() e filter() appartengono agli array, quindi può essere necessario usare lo spread.
  • Considera i riferimenti degli oggetti: Set e Map confrontano gli oggetti in base al riferimento, non confrontando automaticamente il contenuto.

Riepilogo

Set e Map aggiungono a JavaScript strutture dati più espressive rispetto al semplice utilizzo di array e oggetti.

  • Set memorizza valori unici;
  • Map memorizza coppie chiave-valore;
  • entrambe supportano l’iterazione;
  • entrambe offrono metodi specifici per inserimento, ricerca e rimozione;
  • sono utili per eliminare duplicati, creare indici e gestire collezioni dinamiche.

La scelta della struttura corretta rende il codice più leggibile e riduce la necessità di implementare manualmente controlli e ricerche. In un’applicazione reale, utilizzare Set o Map nel punto giusto può semplificare notevolmente la gestione dei dati.

Approfondisci con risorse ufficiali

  • MDN Web Docs – Set: documentazione completa sulla struttura Set, sui suoi metodi e sui comportamenti dei valori.
  • MDN Web Docs – Map: guida ufficiale per creare, modificare e attraversare Map.
  • ECMAScript Language Specification: specifica ufficiale dello standard JavaScript e delle strutture dati integrate.
  • JavaScript.info – Map e Set: spiegazioni ed esercizi pratici per consolidare l’utilizzo di queste collezioni.

SHARE