Recursive Function in Typescript Returning Array with Dynamic Objects

Asked

Viewed 784 times

3

I am beginner in Typescript and tb in Javascript, so I confess not to have much knowledge of the language, therefore, I will describe my problem.

I have the following table in a Postgres database:

inserir a descrição da imagem aqui

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 more or less 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 Father Object contains all its children within, and so on.

Can someone help me?

2 answers

2

Assuming you have received an array with the 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 of code to traverse your array and build 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 in pure Javascript, but can be used inside your TS without problems

Here the fiddle for testing.

2

A very simple way just using the method 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>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.