¿Cómo utilizaría mi función getChildren() para crear una función más grande que tome mis dos matrices principales objs y objRefs y genere una sola matriz de objs que demuestre su relación padre/hijo?
aquí están las dos matrices de datos principales
const objs = [ { name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }, ] const objRefs = [ { parent_id: 5, obj_id: 7 }, // cory child of matt { parent_id: null, obj_id: 6 }, // matt root { parent_id: null, obj_id: 4 }, // sarah root { parent_id: null, obj_id: 5 }, // heather root { parent_id: 5, obj_id: 3 }, // leslie child of matt { parent_id: 4, obj_id: 2 }, // mary child of sarah { parent_id: 3, obj_id: 1 }, // kevin child of leslie ] Mi objetivo es ejecutar una función llamada getFamilyTree() que me devolvería esto...
const tree = [ { id: 5, name: "Matt", age: 53, children:[ { id: 3, name: "Leslie", age: 21, children:[ { id: 1, name: "Kevin", age: 5, children:[ ] } ] }, { id: 7, name: "Cory", age: 19, children:[ ] } ] }, { id: 6, name: "Heather", age: 37, children:[ ] }, { id: 4, name: "Sarah", age: 46, children:[ { id: 2, name: "Marry", age: 30, children:[ ] } ] } ]Tengo una función que me devuelve todos los elementos secundarios para la identificación del nodo principal dada, pero no estoy seguro de cómo estructurar una función para que me devuelva el árbol completo como mi ejemplo.
function getChildren(parent_id) { let children = [] for (var i = 0; i < objRefs.length; i++) { const ref = objRefs[i] if (ref.parent_id === parent_id) { const obj = objs.find(obj => { return obj.id === ref.obj_id }) children.push(obj) } } return children } function getFamilyTree() { let result = [] ... // build recursive family tree return result }No creo que necesites la función getChildren para construir tu árbol. Usar Maps en su lugar podría ser útil:
const objs = [ { name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }, ] const objRefs = [ { parent_id: 5, obj_id: 7 }, // cory child of matt { parent_id: null, obj_id: 6 }, // matt root { parent_id: null, obj_id: 4 }, // sarah root { parent_id: null, obj_id: 5 }, // heather root { parent_id: 5, obj_id: 3 }, // leslie child of matt { parent_id: 4, obj_id: 2 }, // mary child of sarah { parent_id: 3, obj_id: 1 }, // kevin child of leslie ] function getFamillyTree(){ const nodes = new Map() // Preparing the data nodes objs.forEach(elt => nodes.set(elt.id, {...elt, children: [], root: false})) // Linking the nodes to make the parent <-> children relations objRefs.filter(rel => !!rel.parent_id).forEach(rel => { const parent = nodes.get(rel.parent_id) parent.children.push(nodes.get(rel.obj_id)) }) // Marking the roots objRefs.filter(rel => rel.parent_id === null).forEach(rel => { const obj = nodes.get(rel.obj_id) obj.root = true }) return Array.from(nodes.values()).filter(obj => obj.root) } document.write(JSON.stringify(getFamillyTree(), null, 4))Editar: esta respuesta puede estar un poco fuera de lugar, porque como dijo Nina en un comentario sobre la pregunta, OP parece solicitar una solución explícitamente recursiva, dejando esto aquí como referencia.
No necesita una función recursiva para construir eso.
Para obtener una complejidad de tiempo razonable, almacene todos los objs en un Map o algo así (si los id son secuenciales, incluso una matriz funcionará) con clave de id . Luego, solo itere sobre objRefs y construya las relaciones apropiadamente:
const objs = [ { name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }, ] const objRefs = [ { parent_id: 5, obj_id: 7 }, // cory child of matt { parent_id: null, obj_id: 6 }, // matt root { parent_id: null, obj_id: 4 }, // sarah root { parent_id: null, obj_id: 5 }, // heather root { parent_id: 5, obj_id: 3 }, // leslie child of matt { parent_id: 4, obj_id: 2 }, // mary child of sarah { parent_id: 3, obj_id: 1 }, // kevin child of leslie ] function getFamilyTree(objs, objRefs){ const tree = [] const map = new Map( objs.map(e => [e.id, { ...e, children: [] }]) ) for(const {parent_id, obj_id} of objRefs){ if(parent_id === null){ tree.push(map.get(obj_id)) }else{ map.get(parent_id).children.push(map.get(obj_id)) } } return tree } const tree = getFamilyTree(objs, objRefs) console.log(tree)Podría usar algún objeto como referencia a las personas y sus relaciones y mapear los nodos con sus hijos.
const getChildren = parent => (references[parent] || []).map(id => ({ ...nodes[id], children: getChildren(id) })), people = [{ name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }], children = [{ parent_id: 5, obj_id: 7 }, { parent_id: null, obj_id: 6 }, { parent_id: null, obj_id: 4 }, { parent_id: null, obj_id: 5 }, { parent_id: 5, obj_id: 3 }, { parent_id: 4, obj_id: 2 }, { parent_id: 3, obj_id: 1 }], nodes = Object.fromEntries(people.map(o => [o.id, o])), references = children.reduce((r, { parent_id, obj_id }) => ((r[parent_id] ??= []).push(obj_id), r), {}), tree = getChildren(null); console.log(tree); .as-console-wrapper { max-height: 100% !important; top: 0; } Un enfoque con un solo bucle de children .
const getTree = (people, children, root) => { const nodes = Object.fromEntries(people.map(o => [o.id, o])), t = {}; children.forEach(({ parent_id: p, obj_id: id }) => ((t[p] ??= {}).children ??= []).push(Object.assign(t[id] ??= {}, nodes[id])) ); return t[root].children; }, people = [{ name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }], children = [{ parent_id: 5, obj_id: 7 }, { parent_id: null, obj_id: 6 }, { parent_id: null, obj_id: 4 }, { parent_id: null, obj_id: 5 }, { parent_id: 5, obj_id: 3 }, { parent_id: 4, obj_id: 2 }, { parent_id: 3, obj_id: 1 }], tree = getTree(people, children, null); console.log(tree); .as-console-wrapper { max-height: 100% !important; top: 0; }