Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

158
Visualizações
How to aggregate a tree structure programmatically from config-like parent-child array items?

I'd like to change my javascript object structure, into an object which is like hierarchy tree patern object, this is my object:

let input = [
  {'id':1 ,'pid' : 0},
  {'id':2 ,'pid' : 1},
  {'id':3 ,'pid' : 2},
  {'id':4 ,'pid' : 2},
  {'id':5 ,'pid' : 3},
  {'id':6 ,'pid' : 3},
  {'id':7 ,'pid' : 4},
  {'id':8 ,'pid' : 4},
  {'id':9 ,'pid' : 4}
];

and found this snippet on the internet and it actually works well (i forgot who made it, thank you so much anyway)

let input = [
{'id':1 ,'pid' : 0},
{'id':2 ,'pid' : 1},
{'id':3 ,'pid' : 2},
{'id':4 ,'pid' : 2},
{'id':5 ,'pid' : 3},
{'id':6 ,'pid' : 3},
{'id':7 ,'pid' : 4},
{'id':8 ,'pid' : 4},
{'id':9 ,'pid' : 4}
];

let register = {};

let output = {};

for (let el of input) {
  el = Object.assign({}, el);
  register[el.id] = el;
 
  if (!el.pid) { 
    output[el.id] = el;
  } else { 
    register[el.pid][el.id] = el
  }

  delete el.pid;
  delete el.id
}

document.body.innerHTML = "<pre>" + (JSON.stringify(output, undefined, 2))

something i didn't expected came up when i change the PID value with the id from below, i mean, from this {'id':4 ,'pid' : 2} into this {'id':4 ,'pid' : 9}, the result is register[el.pid] is undefined

please help to fix this, thanks in advance

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Aggregating a tree programmatically from parent-child config-like items is possible even when such items are not in perfect order as long as such relationships are valid, thus representable.

Circular parent child references, like what the OP creates/triggers when changing { 'id': 4, 'pid': 2 } to { 'id': 4, 'pid': 9 }, loose the linkage into an already representable overall tree structure. Thus such references are invalid and any other valid substructure which is linked to the former is lost as well.

The above claim proves itself with the next provided example code ...

function aggregateTree( 
  { index = {}, result = {} }, // accumulator.
  { id, pid },                 // parent child config.
) {
  const childItem = (index[id] ??= { [id]: {} });
  const parentItem = (pid !== 0)
    && (index[pid] ??= { [pid]: {} })
    || null;
  const node = (parentItem !== null)
    && parentItem[pid] // programmatically build partial trees.
    || result // assign partial tree references at root/resul level.

  Object.assign(node, childItem);

  return { index, result };
}

console.log('unordered but valid parent child relationships ...', [

  { 'id': 1 ,'pid': 0 },
  { 'id': 2 ,'pid': 1 },
  { 'id': 3 ,'pid': 2 },

  { 'id': 12, 'pid': 0 },

  { 'id': 11, 'pid': 6 },
  { 'id': 10, 'pid': 6 },

  { 'id': 4, 'pid': 5 },

  { 'id': 5 ,'pid': 3 },
  { 'id': 6 ,'pid': 3 },

  { 'id': 7 ,'pid': 4 },
  { 'id': 8 ,'pid': 4 },
  { 'id': 9 ,'pid': 4 }

].reduce(aggregateTree, { result: {} }).result);

console.log('ordered but partially invalid parent child relationships ...', [

  // circular references like 4 to 9 and 9 to 4,
  // thus not being linked to the overall tree,
  // can not be aggregated and displayed.

  { 'id': 1, 'pid': 0 },
  { 'id': 2, 'pid': 1 },
  { 'id': 3, 'pid': 2 },

  { 'id': 4, 'pid': 9 }, // circular thus disconnected.
  // { 'id': 9, 'pid': 4 },

  { 'id': 5, 'pid': 3 },
  { 'id': 6, 'pid': 3 },

  { 'id': 7, 'pid': 4 }, // lost due to being linked to a circular reference.
  { 'id': 8, 'pid': 4 }, // lost due to being linked to a circular reference.

  { 'id': 9, 'pid': 4 }, // circular thus disconnected.
  // { 'id': 4, 'pid': 9 },

].reduce(aggregateTree, { result: {} }).result);
.as-console-wrapper { min-height: 100%!important; top: 0; }

about 4 years ago · Juan Pablo Isaza Relatório

0

Well, you can not move the parent to it's own children. This works only in time travel novels/movies.


For creating a tree without deleting properties, you could take a single loop and take the id and parent as well and as result the object with the root parent 0.

This approach works with unsorted data as well.

const
    input = [{ id: 1, pid: 0 }, { id: 2, pid: 1 }, { id: 3, pid: 2 }, { id: 4, pid: 2 }, { id: 5, pid: 3 }, { id: 6, pid: 3 }, { id: 7, pid: 4 }, { id: 8, pid: 4 }, { id: 9, pid: 4 }],
    tree = {};

for (const { id, pid } of input) {
    tree[pid] ??= {};
    tree[id] ??= {};
    tree[pid][id] ??= tree[id];
}

console.log(tree[0]);
.as-console-wrapper { max-height: 100% !important; top: 0; }

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda