Recursive Function in TypeScript returning Array with Dynamic Objects

0

I am a beginner in TypeScript and tb in JavaScript, so I confess I do not have much knowledge of the language, so I will describe my problem.

I have the following table in a PostGres database:

As you can see, a simple structure where one record references the other in a hierarchical parent-child structure.

What I need to do is a function in typescript that is recursive that returns an array with objects something like this:

[
  {
    id: 1,    
    filhos: [
      {
        id: 11,
        filhos: null
      },
      {
        id: 12,
        filhos: [
          {
            id: 121,
            filhos: null
          },
          {
            id: 122,
            filhos: null
          },
          {
            id: 123,
            filhos: null
          },
          {
            id: 124,
            filhos: null
          }
        ]
      }
    ]
  },
  {
    id: 2,
    filhos: [
      {
        id: 21,
        filhos: null
      },
      {
        id: 22,
        filhos: null
      },
      {
        id: 23,
        filhos: null
      }
    ]
  }    
]

Notice that the Parent Object contains all of its children within, and so on.

Can anyone help me?

    
asked by anonymous 04.03.2018 / 21:47

2 answers

0

Assuming you received an array of Postgres data, as follows:

var arr = [
  {id: 1, idPai: null},
  {id: 2, idPai: null},
  {id: 11, idPai: 1},
  {id: 12, idPai: 1},
  {id: 21, idPai: 2},
  {id: 22, idPai: 2},
  {id: 23, idPai: 2},
  {id: 121, idPai: 12},
  {id: 122, idPai: 12},
  {id: 123, idPai: 12},
  {id: 124, idPai: 12}
];

An example code to traverse your array and mount the hierarchy recursively:

var resultado = [];

function teste(arrEntrada, arrSaida){
    for (let i = 0; i < arrEntrada.length; i++) {
        let item = arrEntrada[i];
        let obj = {
            id: item.id,
            filhos: []
        };
        let filhos = arr.filter(elemento => elemento.idPai === item.id);
        teste(filhos, obj.filhos);

        arrSaida.push(obj);
    }  
}

teste(arr.filter(elemento => elemento.idPai === null), resultado);
console.log(JSON.stringify(resultado));

You can easily adapt to other types of returns.

This example is pure Javascript, but can be used within your TS without problems

Here the fiddle for testing.

    
05.03.2018 / 02:06
0

A very simple way just by using the filter

const arr = [
  { id: 1, idPai: null },
  { id: 2, idPai: null },
  { id: 11, idPai: 1 },
  { id: 12, idPai: 1 },
  { id: 21, idPai: 2 },
  { id: 22, idPai: 2 },
  { id: 23, idPai: 2 },
  { id: 121, idPai: 12 },
  { id: 122, idPai: 12 },
  { id: 123, idPai: 12 },
  { id: 124, idPai: 12 }
];

let resultado = arr.filter(pai => {
  pai.filhos = arr.filter(filho => filho.idPai === pai.id);
  return pai.idPai === null
});

// Apenas para demonstrar a saída!
document.querySelector('pre').innerHTML = JSON.stringify(resultado, null, 2);
<pre></pre>
    
06.03.2018 / 01:40