Destructuring e spread/rest per costruire una pipeline di trasformazione dei dati

by Anastasia P.
SHARE
Destructuring e spread/rest per costruire una pipeline di trasformazione dei dati
© Guida-HTML5.it

Introduzione

Quando un’applicazione riceve dati da più fonti, spesso deve trasformarli prima di utilizzarli. Un prodotto può arrivare da un file JSON, da un database o da un servizio esterno con proprietà non uniformi. In questi casi, il codice rischia di diventare difficile da leggere se accede continuamente a proprietà annidate e costruisce nuovi oggetti manualmente.

Il destructuring assignment permette di estrarre rapidamente valori da oggetti e array. Gli operatori spread e rest, invece, consentono rispettivamente di espandere valori e raccogliere quelli rimanenti. In questo tutorial useremo queste funzionalità per creare una piccola pipeline che normalizza i dati di un catalogo prodotti, applica trasformazioni e produce un risultato pronto per la visualizzazione.

L’esempio è utile perché mostra un caso comune: ricevere dati con proprietà tecniche, rimuovere informazioni inutili, aggiungere valori calcolati e mantenere le funzioni indipendenti e riutilizzabili.

Codice completo

const prodottiRicevuti = [
  {
    id: 101,
    title: "Tastiera meccanica",
    price: 89.9,
    currency: "EUR",
    category: "accessories",
    supplierData: {
      internalCode: "KB-001",
      warehouse: "Milano"
    },
    tags: ["meccanica", "gaming"],
    dimensions: {
      width: 45,
      height: 3
    }
  },
  {
    id: 102,
    title: "Monitor 27 pollici",
    price: 249.5,
    currency: "EUR",
    category: "display",
    supplierData: {
      internalCode: "MN-027",
      warehouse: "Roma"
    },
    tags: ["4k", "usb-c"],
    dimensions: {
      width: 62,
      height: 37
    }
  }
];

// Rest raccoglie le proprietà che non ci interessano direttamente.
function rimuoviDatiTecnici({
  supplierData,
  dimensions,
  ...datiPubblici
}) {
  return datiPubblici;
}

// Destructuring con valori predefiniti e alias.
function aggiungiInformazioni({
  id,
  title: nome,
  price,
  currency = "EUR",
  tags = []
}) {
  const prezzoFormattato = new Intl.NumberFormat("it-IT", {
    style: "currency",
    currency
  }).format(price);

  return {
    id,
    nome,
    prezzo: price,
    prezzoFormattato,
    tags,
    disponibile: price < 300
  };
}

// Spread crea un nuovo oggetto senza modificare quello originale.
function normalizzaProdotto(prodotto) {
  const datiSenzaMetadati = rimuoviDatiTecnici(prodotto);
  const datiArricchiti = aggiungiInformazioni(datiSenzaMetadati);

  return {
    ...datiSenzaMetadati,
    ...datiArricchiti,
    tags: [...datiArricchiti.tags, "catalogo"]
  };
}

const catalogo = prodottiRicevuti.map(normalizzaProdotto);

console.log(catalogo);

Spiegazione

Estrarre e rinominare le proprietà

Nella funzione aggiungiInformazioni il parametro viene destrutturato direttamente nella firma:

function aggiungiInformazioni({
  id,
  title: nome,
  price,
  currency = "EUR",
  tags = []
}) {
  // ...
}

La sintassi title: nome estrae la proprietà title, ma la rende disponibile nel corpo della funzione con il nome nome. Questo è utile quando il nome originale non è coerente con la convenzione usata dall’applicazione.

currency = "EUR" assegna un valore predefinito se la proprietà non esiste o vale undefined. La stessa tecnica viene utilizzata per tags, evitando controlli ripetitivi come prodotto.tags || [].

Usare rest per escludere proprietà

La funzione rimuoviDatiTecnici estrae due proprietà che non devono essere pubblicate e raccoglie tutte le altre in datiPubblici:

function rimuoviDatiTecnici({
  supplierData,
  dimensions,
  ...datiPubblici
}) {
  return datiPubblici;
}

In questo caso supplierData e dimensions non vengono restituiti, mentre id, title, price, currency e tags vengono copiati nel nuovo oggetto. È una tecnica pratica per filtrare metadati interni senza elencare manualmente tutte le proprietà da conservare.

Usare spread per comporre oggetti

Nel ritorno di normalizzaProdotto lo spread combina più oggetti:

return {
  ...datiSenzaMetadati,
  ...datiArricchiti,
  tags: [...datiArricchiti.tags, "catalogo"]
};

Le proprietà successive hanno precedenza su quelle precedenti. Di conseguenza, se due oggetti contengono la stessa chiave, il valore di datiArricchiti sostituisce quello precedente. Infine, l’array tags viene copiato e arricchito con il tag "catalogo".

È importante ricordare che lo spread realizza una copia superficiale. Gli oggetti annidati vengono ancora condivisi, mentre array e oggetti al primo livello vengono copiati.

La pipeline con map

La chiamata:

const catalogo = prodottiRicevuti.map(normalizzaProdotto);

applica la stessa trasformazione a ogni prodotto e restituisce un nuovo array. Il risultato contiene dati più semplici, nomi coerenti, prezzi formattati e una proprietà booleana che indica la disponibilità commerciale.

Best practice

  • Destruttura solo ciò che usi: estrarre decine di proprietà rende la firma difficile da comprendere.
  • Usa alias descrittivi: rinominare title in nome può migliorare la leggibilità quando il dominio dell’applicazione è in italiano.
  • Definisci valori predefiniti: array come tags dovrebbero avere un fallback per evitare errori durante iterazioni e concatenazioni.
  • Ricorda l’ordine dello spread: le proprietà più a destra sovrascrivono quelle precedenti.
  • Non confondere rest e spread: la sintassi è simile, ma rest raccoglie valori, mentre spread li espande.
  • Evita mutazioni: crea nuovi oggetti e nuovi array quando aggiungi o modifichi dati.
  • Separa le responsabilità: una funzione dovrebbe filtrare, arricchire o formattare i dati, non fare tutto contemporaneamente.

Riepilogo

Destructuring, spread e rest sono strumenti fondamentali per costruire trasformazioni di dati concise e leggibili. Il destructuring estrae proprietà e valori, anche con alias e valori predefiniti. Il rest permette di raccogliere le proprietà rimanenti, mentre lo spread consente di creare nuovi oggetti e array combinando dati esistenti.

Nell’esempio abbiamo trasformato un catalogo esterno in una struttura adatta all’interfaccia dell’applicazione, eliminando metadati tecnici e aggiungendo informazioni calcolate. Questo approccio riduce il codice ripetitivo e rende ogni passaggio della pipeline più facile da testare.

Approfondisci con risorse ufficiali

  • MDN - Destructuring assignment: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring
  • MDN - Spread syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
  • MDN - Rest parameters: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
  • ECMAScript Language Specification: https://tc39.es/ecma262/

SHARE