Data looks as follows:
children
key which is either null
or an array of ids.parent
or depth
referenceInput:
const items = [
{
id: 1,
name: 'Item 1',
children: [ 2, 3 ]
},
{
id: 2,
name: 'Item 2',
children: null
},
{
id: 3,
name: 'Item 3',
children: null
},
{
id: 4,
name: 'Item 4',
children: [ 5 ]
},
{
id: 5,
name: 'Item 5',
children: [ 6 ]
},
{
id: 6,
name: 'Item 6',
children: null
},
}
]
Expected Output:
const tree = [
{
id: 1,
name: 'Item 1',
children: [
{
id: 2,
name: 'Item 2',
children: null
},
{
id: 3,
name: 'Item 3',
children: null
},
]
},
{
id: 4,
name: 'Item 4',
children: [
{
id: 5,
name: 'Item 5',
children: [
{
id: 6,
name: 'Item 6',
children: null
}
]
}
]
}
]
If this is in fact possible, would love to 1) see how it is done and 2) see if there are any libraries that handle this use case.
The resulting structure is more a forest than a tree, as not all nodes are connected and you have multiple "roots".
You can first key the nodes by their id in a Map, and then iterate all children arrays to replace their contents by the corresponding items found in the Map. At the same time keep track of all the children, so that at the end you can identify which items are not children, and therefore belong in the result array:
const items = [{id: 1,name: 'Item 1',children: [ 2, 3 ]},{id: 2,name: 'Item 2',children: null},{id: 3,name: 'Item 3',children: null},{id: 4,name: 'Item 4',children: [ 5 ]},{id: 5,name: 'Item 5',children: [ 6 ]},{id: 6,name: 'Item 6',children: null},];
const map = new Map(items.map(item => [item.id, item]));
const children = new Set;
for (const item of items) {
if (!item.children) continue;
for (const id of item.children) children.add(id);
item.children = item.children?.map(id => map.get(id));
}
const forest = items.filter(({id}) => !children.has(id));
console.log(forest);