Reputation: 318
What's the best way to loop through a javascript array, looking for elements of interest and, for each one, make the elements in between "children" of the preceding element of interest?
Essentially, I want to go from flat data that looks like:
[
{
value: "foo",
type: "header!"
},
{
value: "bar",
type: "normal"
},
{
value: "bar",
type: "normal"
},
{
value: "foo",
type: "header!"
},
{
value: "bar",
type: "normal"
}
]
To something more like:
[
{
value: "foo",
type: "header!",
children: [
{
value: "foo",
type: "normal"
},
{
value: "bar",
type: "normal"
}
]
},
{
value: "bar",
type: "header!",
children: [
{
value: "foo",
type: "normal"
}
]
},
]
I think that Array.reduce is what I need here, but I'm struggling with exactly how to make it do what I need.
So far I've tried code that looks like:
const nestedArray = flatArray.map(el => {
if(el.type === "header!") return {
type: el.type,
children: []
}
})
Upvotes: 0
Views: 317
Reputation: 214959
Just loop, check the type field and push it either in the main array or in the children
of the last header:
data = [
{value: "foo", type: "header!"},
{value: "bar", type: "normal"},
{value: "bar", type: "normal"},
{value: "foo", type: "header!"},
{value: "bar", type: "normal"}
]
let tree = [], last
for (let elem of data) {
if (elem.type === 'header!')
tree.push(last = {...elem, children: []})
else
last.children.push(elem)
}
console.log(tree)
As a general advice, try to avoid functions like map
and reduce
when manipulating complex data structures. They are far less readable, harder to reason about and much slower than for..of
loops.
Upvotes: 2