如何对树型结构进行检索
如何对树结构进行检索,并返回完整路径的树结构
近期有个前端需求,用户想要对树进行检索。
需求详情
- 要展示所有条件匹配的节点
- 展示到的节点,若还具有子节点,默认不展开。用户可以继续点击展开查看。
需求分析
- 找到符合条件的节点,并且
代码示例
以简单的三层结构为示例
const treeData = [
{
name: '示例A',
parantId: null,
id: 1,
children: [{
name: '示例AA',
parantId: null,
id: 11,
children: [{
name: '示例AAA',
parantId: null,
id: 111,
children: []
}]
}]
},
{
name: '示例A1',
parantId: null,
id: 2,
children: [{
name: '示例AA1',
parantId: null,
id: 22,
children: [{
name: '示例AAA1',
parantId: null,
id: 222,
children: []
}]
}]
}
]
const keyword = 'AAA1'
const getTree = (treeData, keyword) => {
let nodes = []
let openKey = []
for (let i = 0; i < treeData.length; i++) {
const node = treeData[i]
// 匹配上了。不需要子节点返回了,只需要子节点需要展开到哪里, 储存展开的节点
const { nodes: _nodes, openKey: _openKey } = getTree(node.children, keyword)
if (node.name.includes(keyword)) {
// 需要包含子节点所以储存含子节点的整个节点
nodes.push(node)
// 若不需要包含子节点
// nodes.push({
// ...node,
// children: []
// })
// 若子元素包含匹配的、需要展开自身
if (nodes && nodes.length) {
openKey = _openKey.concat([node.id])
}
} else {
// 若子节点含匹配的则保存该节点
if (_nodes && _nodes.length) {
// 需要包含被过滤后的子节点
nodes.push({
...node,
children: _nodes
})
// 给节点加上展开标识
if (nodes && nodes.length) {
openKey = _openKey.concat([node.id])
}
}
}
}
return { nodes, openKey }
}
// 测试一下
getTree(treeData, keyword)
// 结果
{
nodes: [{
name: '示例A1',
parantId: null,
id: 2,
open: true,
children: [{
name: '示例AA1',
parantId: null,
id: 22,
open: true,
children: [{
name: '示例AAA1',
parantId: null,
id: 222,
children: []
}]
}]
}],
openKey: [222, 22, 2]
}