There is an array of data objects which have parent and child relations in it. I’d like to print the structure of the tree by level, printing only the names. If there is no parent information indicated then it is the root node.
Sample input:
data = [ { id: 1, name: "ABC", parent: 2 }, { id: 2, name: "BCA" }, { id: 3, name: "CBA", parent: 1 }, { id: 4, name: "DDA", parent: 1 }, { id: 5, name: "EFG", parent: 2 } ];
Output:
BCA ABC CBA DDA EFG
I tried using reduce to get the object structure but couldn’t get the traverse logic. Is there better way to get the solution, such that all the child objects will be under a single array?
const data = [{ id: 1, name: "ABC", parent: 2 }, { id: 2, name: "BCA" }, { id: 3, name: "CBA", parent: 1 }, { id: 4, name: "DDA", parent: 1 }]; let root = null; const obj = data.reduce((r, o) => { Object.assign(r[o.id] = r[o.id] || {}, o); if (!o.parent) { root = o.id; } r[o.parent] = r[o.parent] || {}; r[o.parent][o.id] = r[o.id]; return r; }, {}); console.log(obj[root]);
Advertisement
Answer
reduce
is the correct operation because we want to build flat mapping from every node to its children, then return the root. The children
array for each node is needed so we can traverse and print the tree top-down. If parent
references were enough, we’d be done since the original structure already has these.
One approach to produce the nested structure is:
const unflattenTree = data => { const nodes = {}; let root; for (const node of data) { nodes[node.id] = {children: [], ...nodes[node.id], ...node}; if (node.parent) { nodes[node.parent] = {children: [], ...nodes[node.parent]}; nodes[node.parent].children.push(nodes[node.id]); } else { root = nodes[node.id]; } } return root; }; const printTree = (root, gap=4, level=0) => { if (root) { console.log(" ".repeat(level), root.name); root.children?.forEach(e => printTree(e, gap, level + gap)); } }; const data = [ { id: 1, name: "ABC", parent: 2 }, { id: 2, name: "BCA" }, { id: 3, name: "CBA", parent: 1 }, { id: 4, name: "DDA", parent: 1 }, { id: 5, name: "EFG", parent: 2 } ]; printTree(unflattenTree(data));