Given a basic tree like this:
[
{
id: "1"
},
{
id: "2"
},
{
id: "3"
},
{
id: "2.1",
parent_id: "2"
},
{
id: "3.1",
parent_id: "3"
},
{
id: "3.2",
parent_id: "3"
},
{
id: "3.1.1",
parent_id: "3.1"
},
{
id: "3.1.1.1",
parent_id: "3.1.1"
},
{
id: "3.1.1.1.1",
parent_id: "3.1.1.1"
},
{
id: "bohemian rhapsody",
parent_id: "3.2"
}
]
I want to be able to get all descendants starting at an arbitrary level (id).
This works but I am questioning if this is the most efficient way to do this because essentially I am scanning the array at each level
let source = []; // my array here
let getDescendants = (id, source) => {
let result = [];
for (let node of source) {
if (node.id === id) {
result.push(node);
} else if (node.parent_id === id) {
result.push(...getDescendants(node.id, source));
}
}
return result;
};
Expected output of the above when run against ‘3’ is
[{ id: "3" }, { id: "3.1", parent_id: "3" }, { id: "3.1.1", parent_id: "3.1" }, { id: "3.1.1.1", parent_id: "3.1.1" }, { id: "3.1.1.1.1", parent_id: "3.1.1.1" }, { id: "3.2", parent_id: "3" }, { id: "bohemian rhapsody", parent_id: "3.2" }]
Note: I don’t particularly care if this is breadth first
or depth first
; just that it is the most performant approach.
2
Answers
You could perform a search with a single pass. As your dataset grows large, this would be a more performant solution, particularly in a heavily unbalanced tree as it would be comparing an O(N) solution to an O(N*N) solution.
Your optimal solution is affected by how you’re representing your tree as a list. If you were to transform your tree into an object that more closely represents the tree’s structure, your recursive approach could be scoped down to the children of your current node without traversing your entire list.
Here is an alternative solution that works without the
.startsWith()
restriction.id
s as keysforEach()
loop over all.values()
of the object each element is pushed into its parent object’schildren
arrayobj
that do not have aparent_id
are retained in a.filter()
operation and stored in the solution arrayres
.