Reputation: 248
I have the following nested JSON data structure. Each node can have any number of children and the data can be any number of nodes deep.
[{
id : "a",
path : "a"
}, {
id : "b",
path : "b"
}, {
id : "c",
path : "c",
children: [{
id : "a",
path : "c/a"
}, {
id : "b",
path : "c/b",
children: [{
id : "a",
path : "c/b/a"
}, {
id : "b",
path : "c/b/b"
}]
}]
}]
I need to create a function in lodash (v3.10.1) which returns a nested JSON object of matching paths, and any parent objects. For example, if I was to search on "b" the filter should return the following:
[{
id : "b",
path : "b"
}, {
id : "c",
path : "c",
children: [{
id : "b",
path : "c/b",
children: [{
id : "a",
path : "c/b/a"
}, {
id : "b",
path : "c/b/b"
}]
}]
}]
My initial attempt was like this but it did work:
const filterTree = (filter, list) => {
return _.filter(list, (item) => {
if (item.path) {
return _.includes(item.path.toLowerCase(), filter.toLowerCase());
} else if (item.children) {
return !_.isEmpty(filterTree(filter, item.children));
}
});
};
Any help would be much appreciated
Upvotes: 1
Views: 3356
Reputation: 33486
The first issue is that if (item.path)
is always true
, so the recursive calls never happen.
In order to get your desired result, you will have to update item.children
after filtering in the recursive cases, because _.filter
will not mutate the array that you pass to it. If you don't want the input to be mutated, use _.cloneDeep
to make a copy first.
const data = [{"id":"a","path":"a"},{"id":"b","path":"b"},{"id":"c","path":"c","children":[{"id":"a","path":"c/a"},{"id":"b","path":"c/b","children":[{"id":"a","path":"c/b/a"},{"id":"b","path":"c/b/b"}]}]}];
const filterTree = (filter, list) => {
return _.filter(list, (item) => {
if (_.includes(_.toLower(item.path), _.toLower(filter))) {
return true;
} else if (item.children) {
item.children = filterTree(filter, item.children);
return !_.isEmpty(item.children);
}
});
};
console.log(filterTree('b', data));
.as-console-wrapper { max-height: 100% !important; }
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Upvotes: 2