我有以下嵌套的JSON数据结构。每个节点可以有任意数量的子节点,数据可以是任意数量的节点。
[{
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"
}]
}]
}]
我需要在lodash(v3.10.1)中创建一个函数,该函数返回匹配路径和任何父对象的嵌套JSON对象。 例如,如果我要搜索" b"过滤器应返回以下内容:
[{
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"
}]
}]
}]
我最初的尝试是这样的,但确实有效:
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));
}
});
};
非常感谢任何帮助
答案 0 :(得分:2)
第一个问题是if (item.path)
总是true
,所以递归调用永远不会发生。
为了获得所需的结果,在递归情况下过滤后,您必须更新item.children
,因为_.filter
不会改变您传递给它的数组。如果您不希望输入发生变异,请先使用_.cloneDeep
制作副本。
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>
&#13;