Javascript 树视图搜索
Javascript Tree view Search
我正在尝试使用 JavaScript 实现树视图搜索。我发现 很有用,但提供的答案在我的场景中没有预期的输出。
示例输入:
[
{
"id": 1,
"templateName": "Item 1",
"isFolder": "true",
"children": [
{
"id": 2,
"templateName": "Subitem 1",
"isFolder": "true",
"children": [
{
"id": 3,
"templateName": "Misc 1",
"isFolder": "true",
"children": [
{
"id": 4,
"templateName": "Misc 2"
}
]
}
]
},
{
"id": 5,
"templateName": "Subitem 2",
"isFolder": "true",
"children": [
{
"id": 6,
"templateName": "Misc 3"
}
]
}
]
},
{
"id": 7,
"templateName": "Item 2",
"isFolder": "true",
"children": [
{
"id": 8,
"templateName": "Subitem 1",
"isFolder": "true",
"children": [
{
"id": 9,
"templateName": "Misc 1"
}
]
},
{
"id": 10,
"templateName": "Subitem 8",
"isFolder": "true",
"children": [
{
"id": 11,
"templateName": "Misc 4"
},
{
"id": 12,
"templateName": "Misc 5"
},
{
"id": 13,
"templateName": "Misc 6",
"isFolder": "true",
"children": [
{
"id": 14,
"templateName": "Misc 7"
}
]
}
]
}
]
}
]
如果我搜索 Subitem 1
,那么预期的输出是:
[
{
"id": 1,
"templateName": "Item 1",
"isFolder": "true",
"children": [
{
"id": 2,
"templateName": "Subitem 1",
"isFolder": "true",
"children": [
{
"id": 3,
"templateName": "Misc 1",
"isFolder": "true",
"children": [
{
"id": 4,
"templateName": "Misc 2"
}
]
}
]
}
]
},
{
"id": 7,
"templateName": "Item 2",
"isFolder": "true",
"children": [
{
"id": 8,
"templateName": "Subitem 1",
"isFolder": "true",
"children": [
{
"id": 9,
"templateName": "Misc 1"
}
]
}
]
}
]
但引用的问答中的答案 returns 对象没有 children
属性。
我尝试修改该答案的代码,还添加了 isFolder
道具以进行额外验证以帮助我。但是我无法return上面的预期输出。
您可以使用复制树的递归函数来执行此操作,但只保留具有更深匹配的子项。当一个节点匹配时,不需要更深层次的递归,因为该节点下的整个子树仍然包含在内。
这里我用了map
和一个链式的filter(Boolean)
。您可以使用 reduce
实现相同的效果。当以该节点为根的子树中某处没有匹配项时,map
会将节点映射到 false
。这些 false
值然后被 filter(Boolean)
:
消除
function deepFilter(nodes, cb) {
return nodes.map(node => {
if (cb(node)) return node;
let children = deepFilter(node.children || [], cb);
return children.length && { ...node, children };
}).filter(Boolean);
}
const forest = [{"id": 1,"templateName": "Item 1","isFolder": "true","children": [{"id": 2,"templateName": "Subitem 1","isFolder": "true","children": [{"id": 3,"templateName": "Misc 1","isFolder": "true","children": [{"id": 4,"templateName": "Misc 2"}]}]},{"id": 5,"templateName": "Subitem 2","isFolder": "true","children": [{"id": 6,"templateName": "Misc 3"}]}]},{"id": 7,"templateName": "Item 2","isFolder": "true","children": [{"id": 8,"templateName": "Subitem 1","isFolder": "true","children": [{"id": 9,"templateName": "Misc 1"}]},{"id": 10,"templateName": "Subitem 8","isFolder": "true","children": [{"id": 11,"templateName": "Misc 4"},{"id": 12,"templateName": "Misc 5"},{"id": 13,"templateName": "Misc 6","isFolder": "true","children": [{"id": 14,"templateName": "Misc 7"}]}]}]}];
const result = deepFilter(forest, node =>
node.templateName.includes("Subitem 1")
);
console.log(result);
我正在尝试使用 JavaScript 实现树视图搜索。我发现
示例输入:
[
{
"id": 1,
"templateName": "Item 1",
"isFolder": "true",
"children": [
{
"id": 2,
"templateName": "Subitem 1",
"isFolder": "true",
"children": [
{
"id": 3,
"templateName": "Misc 1",
"isFolder": "true",
"children": [
{
"id": 4,
"templateName": "Misc 2"
}
]
}
]
},
{
"id": 5,
"templateName": "Subitem 2",
"isFolder": "true",
"children": [
{
"id": 6,
"templateName": "Misc 3"
}
]
}
]
},
{
"id": 7,
"templateName": "Item 2",
"isFolder": "true",
"children": [
{
"id": 8,
"templateName": "Subitem 1",
"isFolder": "true",
"children": [
{
"id": 9,
"templateName": "Misc 1"
}
]
},
{
"id": 10,
"templateName": "Subitem 8",
"isFolder": "true",
"children": [
{
"id": 11,
"templateName": "Misc 4"
},
{
"id": 12,
"templateName": "Misc 5"
},
{
"id": 13,
"templateName": "Misc 6",
"isFolder": "true",
"children": [
{
"id": 14,
"templateName": "Misc 7"
}
]
}
]
}
]
}
]
如果我搜索 Subitem 1
,那么预期的输出是:
[
{
"id": 1,
"templateName": "Item 1",
"isFolder": "true",
"children": [
{
"id": 2,
"templateName": "Subitem 1",
"isFolder": "true",
"children": [
{
"id": 3,
"templateName": "Misc 1",
"isFolder": "true",
"children": [
{
"id": 4,
"templateName": "Misc 2"
}
]
}
]
}
]
},
{
"id": 7,
"templateName": "Item 2",
"isFolder": "true",
"children": [
{
"id": 8,
"templateName": "Subitem 1",
"isFolder": "true",
"children": [
{
"id": 9,
"templateName": "Misc 1"
}
]
}
]
}
]
但引用的问答中的答案 returns 对象没有 children
属性。
我尝试修改该答案的代码,还添加了 isFolder
道具以进行额外验证以帮助我。但是我无法return上面的预期输出。
您可以使用复制树的递归函数来执行此操作,但只保留具有更深匹配的子项。当一个节点匹配时,不需要更深层次的递归,因为该节点下的整个子树仍然包含在内。
这里我用了map
和一个链式的filter(Boolean)
。您可以使用 reduce
实现相同的效果。当以该节点为根的子树中某处没有匹配项时,map
会将节点映射到 false
。这些 false
值然后被 filter(Boolean)
:
function deepFilter(nodes, cb) {
return nodes.map(node => {
if (cb(node)) return node;
let children = deepFilter(node.children || [], cb);
return children.length && { ...node, children };
}).filter(Boolean);
}
const forest = [{"id": 1,"templateName": "Item 1","isFolder": "true","children": [{"id": 2,"templateName": "Subitem 1","isFolder": "true","children": [{"id": 3,"templateName": "Misc 1","isFolder": "true","children": [{"id": 4,"templateName": "Misc 2"}]}]},{"id": 5,"templateName": "Subitem 2","isFolder": "true","children": [{"id": 6,"templateName": "Misc 3"}]}]},{"id": 7,"templateName": "Item 2","isFolder": "true","children": [{"id": 8,"templateName": "Subitem 1","isFolder": "true","children": [{"id": 9,"templateName": "Misc 1"}]},{"id": 10,"templateName": "Subitem 8","isFolder": "true","children": [{"id": 11,"templateName": "Misc 4"},{"id": 12,"templateName": "Misc 5"},{"id": 13,"templateName": "Misc 6","isFolder": "true","children": [{"id": 14,"templateName": "Misc 7"}]}]}]}];
const result = deepFilter(forest, node =>
node.templateName.includes("Subitem 1")
);
console.log(result);