Reputation: 151
First of all, I just want to mention that I really tried to find solution for my problem, but I couldn't find anything that would fit me. Thing is, I have such array:
const arr = [
{
leafName: 'name1',
nodes: [1,2,3,4]
},
{
leafName: 'name2',
nodes: [1,2,3,4]
},
{
leafName: 'name3',
nodes: [1,2,4,5]
},
{
leafName: 'name4',
nodes: [6]
}
];
and what I expect to have is this:
const expectedTree = {
name: 'some root name',
children: [
{
name: 1,
children: [
{
name: 2,
children: [
{
name: 3,
children: [
{
name: 4,
children: [
{
name: 'name1'
},
{
name: 'name2'
}
]
}
]
},
{
name: 4,
children: [
{
name: 5,
children: [
{
name: 'name3'
}
]
}
]
}
]
}
]
},
{
name: 6,
children: [
{
name: 'name4'
}
]
}
]
};
as you can see leafName
should be last node in tree branch. Also if there is partial match from root node to some other node, new child should be added from node which matches last. For example let's take arr[1].nodes
and arr[2].nodes
first two members match, so that means that they should be in same branch just 4 and 5 from arr[2].nodes
split to separate branch(as children for { name: 2, children: [should go here] }
). I really hope you get the idea and I also hope that someone will help me with this. Because I am stuck with this for two days now and I couldn't figure out 'clean' solution for this myself.
Any comments would be very appreciated. ;)
Upvotes: 1
Views: 231
Reputation: 386522
You could loop the array and the nodes and reduce nodes by looking at same name for each level. If a node does not exist, create a new one and return the children of the node.
var array = [{ leafName: 'name1', nodes: [1, 2, 3, 4] }, { leafName: 'name2', nodes: [1, 2, 3, 4] }, { leafName: 'name3', nodes: [1, 2, 4, 5] }, { leafName: 'name4', nodes: [6] }],
result = [];
array.forEach(({ leafName, nodes }) => {
nodes
.reduce((level, name) => {
var temp = level.find(o => o.name === name);
if (!temp) {
level.push(temp = { name });
}
return temp.children = temp.children || [];
}, result)
.push({ name: leafName });
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2