The bigger problem I am trying to solve is, given this data:
var data = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4, children: [
{ id: 6 },
{ id: 7, children: [
{id: 8 },
{id: 9 }
]}
]},
{ id: 5 }
]
I want to make a function findById(data, id) that returns { id: id }. For example, findById(data, 8) should return { id: 8 }, and findById(data, 4) should return { id: 4, children: [...] }.
To implement this, I used Array.prototype.find recursively, but ran into trouble when the return keeps mashing the objects together. My implementation returns the path to the specific object.
For example, when I used findById(data, 8), it returns the path to { id: 8 }:
{ id: 4, children: [ { id: 6 }, { id: 7, children: [ { id: 8}, { id: 9] } ] }
Instead I would like it to simply return
{ id: 8 }
Implementation (Node.js v4.0.0)
var data = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4, children: [
{ id: 6 },
{ id: 7, children: [
{id: 8 },
{id: 9 }
]}
]},
{ id: 5 }
]
function findById(arr, id) {
return arr.find(a => {
if (a.children && a.children.length > 0) {
return a.id === id ? true : findById(a.children, id)
} else {
return a.id === id
}
})
return a
}
console.log(findById(data, 8)) // Should return { id: 8 }
// Instead it returns the "path" block: (to reach 8, you go 4->7->8)
//
// { id: 4,
// children: [ { id: 6 }, { id: 7, children: [ {id: 8}, {id: 9] } ] }
Advertisement
Answer
I would just use a regular loop and recursive style search:
function findById(data, id) {
for(var i = 0; i < data.length; i++) {
if (data[i].id === id) {
return data[i];
} else if (data[i].children && data[i].children.length && typeof data[i].children === "object") {
findById(data[i].children, id);
}
}
}
//findById(data, 4) => Object {id: 4, children: Array[2]}
//findById(data, 8) => Object {id: 8}