Search code examples
javascriptarraystypescripttreetreeview

Build tree array from flat object array in typescript


I have the following JSON:

 "response": [
 {
  "id": 2,
  "alias": "BOAZ01",
  "descrizione": "ISTANZA DA VALUTARE",
  "dataCreazione": "2022-12-21T09:01:09.972819",
  "dataAggiornamento": "2022-12-21T09:01:09.972776",
  "dataDisabilitazione": null,
  "abilitato": true,
  "attivita": null
},
{
  "id": 4,
  "alias": "BOAZ02",
  "descrizione": "ISTANZA IN VALUTAZIONE",
  "dataCreazione": "2022-12-21T09:01:58.87955",
  "dataAggiornamento": "2022-12-21T09:01:58.879506",
  "dataDisabilitazione": null,
  "abilitato": true,
  "attivita": {
    "id": 2,
    "alias": "BOAZ01",
    "descrizione": "ISTANZA DA VALUTARE",
    "dataCreazione": "2022-12-21T09:01:09.972819",
    "dataAggiornamento": "2022-12-21T09:01:09.972776",
    "dataDisabilitazione": null,
    "abilitato": true,
    "assegnazione": null,
    "operatoreCorrente": {
      "codiceFiscale": "YNDKPR83A07I282K",
      "nome": "SUPERADMIN",
      "cognome": "ZERODD",
      "email": "superadmin@zerodd.it",
      "dataCreazione": "2022-12-14T16:30:02.02323",
      "dataAggiornamento": "2022-12-14T16:48:30.933103",
      "abilitazioneEmail": true,
      "tipo": "SUPERPOTERI",
      "hibernateLazyInitializer": {

      }
    }
  }
},
{
  "id": 5,
  "alias": "BOAZ03",
  "descrizione": "ISTANZA VALUTATA",
  "dataCreazione": "2022-12-21T09:02:14.445142",
  "dataAggiornamento": "2022-12-21T09:02:14.4451",
  "dataDisabilitazione": null,
  "abilitato": true,
  "attivita": {
    "id": 4,
    "alias": "BOAZ02",
    "descrizione": "ISTANZA IN VALUTAZIONE",
    "dataCreazione": "2022-12-21T09:01:58.87955",
    "dataAggiornamento": "2022-12-21T09:01:58.879506",
    "dataDisabilitazione": null,
    "abilitato": true,
    "assegnazione": null,
    "operatoreCorrente": {
      "codiceFiscale": "YNDKPR83A07I282K",
      "nome": "SUPERADMIN",
      "cognome": "ZERODD",
      "email": "superadmin@zerodd.it",
      "dataCreazione": "2022-12-14T16:30:02.02323",
      "dataAggiornamento": "2022-12-14T16:48:30.933103",
      "abilitazioneEmail": true,
      "tipo": "SUPERPOTERI",
      "hibernateLazyInitializer": {

      }
    }
  }
},
{
  "id": 6,
  "alias": "BOAZ03.1",
  "descrizione": "ISTANZA VALUTATA-AMMISSIBILE",
  "dataCreazione": "2022-12-21T09:02:40.046325",
  "dataAggiornamento": "2022-12-21T09:02:40.046285",
  "dataDisabilitazione": null,
  "abilitato": true,
  "attivita": {
    "id": 5,
    "alias": "BOAZ03",
    "descrizione": "ISTANZA VALUTATA",
    "dataCreazione": "2022-12-21T09:02:14.445142",
    "dataAggiornamento": "2022-12-21T09:02:14.4451",
    "dataDisabilitazione": null,
    "abilitato": true,
    "assegnazione": null,
    "operatoreCorrente": {
      "codiceFiscale": "YNDKPR83A07I282K",
      "nome": "SUPERADMIN",
      "cognome": "ZERODD",
      "email": "superadmin@zerodd.it",
      "dataCreazione": "2022-12-14T16:30:02.02323",
      "dataAggiornamento": "2022-12-14T16:48:30.933103",
      "abilitazioneEmail": true,
      "tipo": "SUPERPOTERI",
      "hibernateLazyInitializer": {

      }
    }
  }
},
{
  "id": 7,
  "alias": "BOAZ03.2",
  "descrizione": "ISTANZA VALUTATA-INAMMISSIBILE",
  "dataCreazione": "2022-12-21T09:02:54.895132",
  "dataAggiornamento": "2022-12-21T09:02:54.8951",
  "dataDisabilitazione": null,
  "abilitato": true,
  "attivita": {
    "id": 5,
    "alias": "BOAZ03",
    "descrizione": "ISTANZA VALUTATA",
    "dataCreazione": "2022-12-21T09:02:14.445142",
    "dataAggiornamento": "2022-12-21T09:02:14.4451",
    "dataDisabilitazione": null,
    "abilitato": true,
    "assegnazione": null,
    "operatoreCorrente": {
      "codiceFiscale": "YNDKPR83A07I282K",
      "nome": "SUPERADMIN",
      "cognome": "ZERODD",
      "email": "superadmin@zerodd.it",
      "dataCreazione": "2022-12-14T16:30:02.02323",
      "dataAggiornamento": "2022-12-14T16:48:30.933103",
      "abilitazioneEmail": true,
      "tipo": "SUPERPOTERI",
      "hibernateLazyInitializer": {

      }
    }
  }
}]

and i need to get the following tree JSON:

[{
"id": 2,
"alias": "BOAZ01",
"descrizione": "ISTANZA DA VALUTARE",
"dataCreazione": "2022-12-21T09:01:09.972819",
"dataAggiornamento": "2022-12-21T09:01:09.972776",
"dataDisabilitazione": null,
"abilitato": true,
"children": [
  {
    "id": 4,
    "alias": "BOAZ02",
    "descrizione": "ISTANZA IN VALUTAZIONE",
    "dataCreazione": "2022-12-21T09:01:58.87955",
    "dataAggiornamento": "2022-12-21T09:01:58.879506",
    "dataDisabilitazione": null,
    "abilitato": true,
    "children": [
      {
        "id": 5,
        "alias": "BOAZ03",
        "descrizione": "ISTANZA VALUTATA",
        "dataCreazione": "2022-12-21T09:02:14.445142",
        "dataAggiornamento": "2022-12-21T09:02:14.4451",
        "dataDisabilitazione": null,
        "abilitato": true,
        "children": [
          {
            "id": 6,
            "alias": "BOAZ03.1",
            "descrizione": "ISTANZA VALUTATA-AMMISSIBILE",
            "dataCreazione": "2022-12-21T09:02:40.046325",
            "dataAggiornamento": "2022-12-21T09:02:40.046285",
            "dataDisabilitazione": null,
            "abilitato": true
          },
          {
            "id": 7,
            "alias": "BOAZ03.2",
            "descrizione": "ISTANZA VALUTATA-INAMMISSIBILE",
            "dataCreazione": "2022-12-21T09:02:54.895132",
            "dataAggiornamento": "2022-12-21T09:02:54.8951",
            "dataDisabilitazione": null,
            "abilitato": true
          }
        ]
      }
    ]
  }
]}]

I've already got to transform the following Json into a tree structure, using the following code:

 const nest = (items, id = null, link = 'parent_id') =>
  items
    .filter(item => item[link] === id)
    .map(item => ({ ...item, children: nest(items, item.id) }));

console.log(
  nest(comments)
)

on a simpler structure like the following:

const comments = [{
    id: 1,
    parent_id: null
}, {
    id: 2,
    parent_id: 1
}, {
    id: 3,
    parent_id: 1
}, {
    id: 4,
    parent_id: 2
}, {
    id: 5,
    parent_id: 4
}];

but it rightfully can't work since the properties are nested in recursive objects.

Some advice? Thank you all.


Solution

  • You could take a single loop approach by taking node and parent nodes as reference to each other and get the nodes without having parent nodes.

    const
        data = [{ id: 2, alias: "BOAZ01", descrizione: "ISTANZA DA VALUTARE", dataCreazione: "2022-12-21T09:01:09.972819", dataAggiornamento: "2022-12-21T09:01:09.972776", dataDisabilitazione: null, abilitato: true, attivita: null }, { id: 4, alias: "BOAZ02", descrizione: "ISTANZA IN VALUTAZIONE", dataCreazione: "2022-12-21T09:01:58.87955", dataAggiornamento: "2022-12-21T09:01:58.879506", dataDisabilitazione: null, abilitato: true, attivita: { id: 2, alias: "BOAZ01", descrizione: "ISTANZA DA VALUTARE", dataCreazione: "2022-12-21T09:01:09.972819", dataAggiornamento: "2022-12-21T09:01:09.972776", dataDisabilitazione: null, abilitato: true, assegnazione: null, operatoreCorrente: { codiceFiscale: "YNDKPR83A07I282K", nome: "SUPERADMIN", cognome: "ZERODD", email: "superadmin@zerodd.it", dataCreazione: "2022-12-14T16:30:02.02323", dataAggiornamento: "2022-12-14T16:48:30.933103", abilitazioneEmail: true, tipo: "SUPERPOTERI", hibernateLazyInitializer: {} } } }, { id: 5, alias: "BOAZ03", descrizione: "ISTANZA VALUTATA", dataCreazione: "2022-12-21T09:02:14.445142", dataAggiornamento: "2022-12-21T09:02:14.4451", dataDisabilitazione: null, abilitato: true, attivita: { id: 4, alias: "BOAZ02", descrizione: "ISTANZA IN VALUTAZIONE", dataCreazione: "2022-12-21T09:01:58.87955", dataAggiornamento: "2022-12-21T09:01:58.879506", dataDisabilitazione: null, abilitato: true, assegnazione: null, operatoreCorrente: { codiceFiscale: "YNDKPR83A07I282K", nome: "SUPERADMIN", cognome: "ZERODD", email: "superadmin@zerodd.it", dataCreazione: "2022-12-14T16:30:02.02323", dataAggiornamento: "2022-12-14T16:48:30.933103", abilitazioneEmail: true, tipo: "SUPERPOTERI", hibernateLazyInitializer: {} } } }, { id: 6, alias: "BOAZ03.1", descrizione: "ISTANZA VALUTATA-AMMISSIBILE", dataCreazione: "2022-12-21T09:02:40.046325", dataAggiornamento: "2022-12-21T09:02:40.046285", dataDisabilitazione: null, abilitato: true, attivita: { id: 5, alias: "BOAZ03", descrizione: "ISTANZA VALUTATA", dataCreazione: "2022-12-21T09:02:14.445142", dataAggiornamento: "2022-12-21T09:02:14.4451", dataDisabilitazione: null, abilitato: true, assegnazione: null, operatoreCorrente: { codiceFiscale: "YNDKPR83A07I282K", nome: "SUPERADMIN", cognome: "ZERODD", email: "superadmin@zerodd.it", dataCreazione: "2022-12-14T16:30:02.02323", dataAggiornamento: "2022-12-14T16:48:30.933103", abilitazioneEmail: true, tipo: "SUPERPOTERI", hibernateLazyInitializer: {} } } }, { id: 7, alias: "BOAZ03.2", descrizione: "ISTANZA VALUTATA-INAMMISSIBILE", dataCreazione: "2022-12-21T09:02:54.895132", dataAggiornamento: "2022-12-21T09:02:54.8951", dataDisabilitazione: null, abilitato: true, attivita: { id: 5, alias: "BOAZ03", descrizione: "ISTANZA VALUTATA", dataCreazione: "2022-12-21T09:02:14.445142", dataAggiornamento: "2022-12-21T09:02:14.4451", dataDisabilitazione: null, abilitato: true, assegnazione: null, operatoreCorrente: { codiceFiscale: "YNDKPR83A07I282K", nome: "SUPERADMIN", cognome: "ZERODD", email: "superadmin@zerodd.it", dataCreazione: "2022-12-14T16:30:02.02323", dataAggiornamento: "2022-12-14T16:48:30.933103", abilitazioneEmail: true, tipo: "SUPERPOTERI", hibernateLazyInitializer: {} } } }],
        tree = data
            .reduce((t, { attivita, ...o }) => {
                const parent = attivita?.id ?? 'root';
                Object.assign(t[o.id] = t[o.id] || {}, o);
                ((t[parent] ??= {}).children ??= []).push(t[o.id]);
                return t;
            }, {})
            .root
            .children;
    
    console.log(tree);
    .as-console-wrapper { max-height: 100% !important; top: 0; }