I have the following nested JSON payload, which I'd like to iterate through, and find a matching id
value, using lodash
(I'm clearly still getting to grips with lodash
). Below is an example of the payload, and the function I'm using - which seems a bit verbose. Is there an easier way to accomplish what I need?
JSON Payload:
{
"_expanded": true,
"_canDrop": false,
"_id": "-1",
"_name": "root",
"_children": [
{
"_expanded": true,
"_canDrop": false,
"_id": "1",
"_name": "Child 1",
"_children": [
{
"_expanded": true,
"_canDrop": false,
"_id": "1-1",
"_name": "Child 1-1",
"_children": [
{
"_expanded": false,
"_canDrop": false,
"_id": "1-1-1",
"_name": "Child 1-1-1",
"_children": []
}
]
},
{
"_expanded": false,
"_canDrop": false,
"_id": "1-2",
"_name": "Child 1-2",
"_children": []
},
{
"_expanded": false,
"_canDrop": false,
"_id": "1-3",
"_name": "Child 1-3",
"_children": []
}
]
},
{
"_expanded": true,
"_canDrop": false,
"_id": "2",
"_name": "Child 2",
"_children": [
{
"_expanded": false,
"_canDrop": false,
"_id": "2-2",
"_name": "Child 2-2",
"_children": []
}
]
}
]
}
Function:
public findNode = (id: any): TreeNode => {
let result = null;
_.find(this._children, function(child) {
if (child._id === id) {
result = child;
} else {
if (child._children.length > 0) {
_.find(child._children, function(item) {
result = this.findNode(item._id);
})
}
}
});
return result;
}
Lodash doesn't have anything related to deep search, so you have to implement tree aspect of algorithm by yourself.
Additionaly _.find
that you've tried to use is used to find element that matches predicate, but doesn't allow you to change result. It can at best find only a root node he or one of his children has proper _id
.
So, this algorithm must be written manually:
function findNode(id: any, node: any) {
if (node._id === id) {
return node;
}
for (const child of node._children) {
const r = findNode(id, child);
if (r !== undefined) {
return r;
}
}
return undefined;
}
If you really insist to be more 'functional', you can use reduce to replace for loop over children
:
return _.reduce(node._children, (result, child) => {
if (result !== undefined) {
return result;
}
return findNode(id, child);
}, undefined)
This basically iterates over children and checks each children unless something was already found