I need to filter objects recursively in a deeply nested array of objects using javascript, maybe with the help of lodash. What is the cleanest way to do it, If I don't know how many nested object there will be in my array?
Let's say I have the following structure
[
{
label: "first",
id: 1,
children: []
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children: []
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children: []
}
]
}
]
},
{
label: "fourth",
id: 4,
children: []
}
]
}
];
I want to find the one with id 6
, and if it has children return true otherwise false.
Of course If I have a similar data structure but with different number of items it should work too.
How do I find the value of a nested object? If you need to search for a nested object, you can use Lodash's . find() function.It takes three arguments: collection : which can be either an array or object.
var a; a = { b: { c: 'd' } }; function isset (fn) { var value; try { value = fn(); } catch (e) { value = undefined; } finally { return value !== undefined; } }; // ES5 console. log( isset(function () { return a. b.
The sub-properties of objects can be accessed by chaining together the dot or bracket notation .
To access an element of the multidimensional array, you first use square brackets to access an element of the outer array that returns an inner array; and then use another square bracket to access the element of the inner array.
Since you only want a true
of false
answer you can use some()
on the recursion, effectively doing a depth-first search, and make it pretty succinct:
let arr = [{label: "first",id: 1,children: []},{label: "second",id: 2,children: [{label: "third",id: 3,children: [{label: "fifth",id: 5,children: []},{label: "sixth",id: 6,children: [{label: "seventh",id: 7,children: []}]}]},{label: "fourth",id: 4,children: []}]}];
function findNested(arr, id) {
let found = arr.find(node => node.id === id)
return found
? found.children.length > 0
: arr.some((c) => findNested(c.children, id))
}
console.log(findNested(arr, 6)) // True: found with children
console.log(findNested(arr, 7)) // False: found no children
console.log(findNested(arr, 97)) // False: not found
Perhaps a recursive solution along the lines of this might work for you? Here, the node with supplied id is recursively searched for through the 'children' of the supplied input data. If a child node with matching id is found, a boolean result is returned based on the existence of data in that nodes children
array:
function nodeWithIdHasChildren(children, id) {
for(const child of children) {
// If this child node matches supplied id, then check to see if
// it has data in it's children array and return true/false accordinly
if(child.id === id) {
if(Array.isArray(child.children) && child.children.length > 0) {
return true
}
else {
return false
}
}
else {
const result = nodeWithIdHasChildren(child.children, id);
// If result returned from this recursion branch is not undefined
// then assume it's true or false from a node matching the supplied
// id. Pass the return result up the call stack
if(result !== undefined) {
return result
}
}
}
}
const data = [
{
label: "first",
id: 1,
children: []
},
{
label: "second",
id: 2,
children: [
{
label: "third",
id: 3,
children: [
{
label: "fifth",
id: 5,
children: []
},
{
label: "sixth",
id: 6,
children: [
{
label: "seventh",
id: 7,
children: []
}
]
}
]
},
{
label: "fourth",
id: 4,
children: []
}
]
}
];
console.log('node 6 has children:', nodeWithIdHasChildren( data, 6 ) )
console.log('node 7 has children:', nodeWithIdHasChildren( data, 7 ) )
console.log('node 100 has children:', nodeWithIdHasChildren( data, 7 ), '(because node 100 does not exist)' )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With