The bigger problem I am trying to solve is, given this data:
JavaScript
x
14
14
1
var data = [
2
{ id: 1 },
3
{ id: 2 },
4
{ id: 3 },
5
{ id: 4, children: [
6
{ id: 6 },
7
{ id: 7, children: [
8
{id: 8 },
9
{id: 9 }
10
]}
11
]},
12
{ id: 5 }
13
]
14
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 }
:
JavaScript
1
2
1
{ id: 4, children: [ { id: 6 }, { id: 7, children: [ { id: 8}, { id: 9] } ] }
2
Instead I would like it to simply return
JavaScript
1
2
1
{ id: 8 }
2
Implementation (Node.js v4.0.0)
JavaScript
1
32
32
1
var data = [
2
{ id: 1 },
3
{ id: 2 },
4
{ id: 3 },
5
{ id: 4, children: [
6
{ id: 6 },
7
{ id: 7, children: [
8
{id: 8 },
9
{id: 9 }
10
]}
11
]},
12
{ id: 5 }
13
]
14
15
function findById(arr, id) {
16
return arr.find(a => {
17
if (a.children && a.children.length > 0) {
18
return a.id === id ? true : findById(a.children, id)
19
} else {
20
return a.id === id
21
}
22
})
23
return a
24
}
25
26
console.log(findById(data, 8)) // Should return { id: 8 }
27
28
// Instead it returns the "path" block: (to reach 8, you go 4->7->8)
29
//
30
// { id: 4,
31
// children: [ { id: 6 }, { id: 7, children: [ {id: 8}, {id: 9] } ] }
32
Advertisement
Answer
I would just use a regular loop and recursive style search:
JavaScript
1
13
13
1
function findById(data, id) {
2
for(var i = 0; i < data.length; i++) {
3
if (data[i].id === id) {
4
return data[i];
5
} else if (data[i].children && data[i].children.length && typeof data[i].children === "object") {
6
findById(data[i].children, id);
7
}
8
}
9
}
10
11
//findById(data, 4) => Object {id: 4, children: Array[2]}
12
//findById(data, 8) => Object {id: 8}
13