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}