Me gustaría cambiar la estructura de mi objeto javascript, en un objeto que es como un objeto patrón de árbol de jerarquía, este es mi objeto:
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} ];y encontré este fragmento en Internet y en realidad funciona bien (olvidé quién lo hizo, muchas gracias de todos modos)
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)) surgió algo que no esperaba cuando cambié el valor de PID con la identificación de abajo, es decir, de este {'id':4 ,'pid' : 2} a este {'id':4 ,'pid' : 9} , el resultado es register[el.pid] is undefined
por favor ayuda a solucionar esto, gracias de antemano
Es posible agregar un árbol programáticamente a partir de elementos similares a la configuración padre-hijo incluso cuando dichos elementos no están en perfecto orden, siempre que tales relaciones sean válidas y, por lo tanto, representable.
Las referencias circulares entre padres e hijos, como lo que el OP crea/activa al cambiar { 'id': 4, 'pid': 2 } a { 'id': 4, 'pid': 9 } , pierden el enlace en un general ya representable estructura de árbol. Por lo tanto, tales referencias no son válidas y cualquier otra subestructura válida que esté vinculada a la anterior también se pierde.
La afirmación anterior se demuestra con el siguiente código de ejemplo proporcionado...
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; }Bueno, no puedes mover el padre a sus propios hijos. Esto funciona solo en novelas/películas de viajes en el tiempo.
Para crear un árbol sin eliminar propiedades, puede tomar un solo ciclo y tomar la identificación y el padre también y como resultado el objeto con el padre raíz 0 .
Este enfoque también funciona con datos no ordenados.
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; }