预期结果:
const treeList = [
{
id: 1,
name: '根节点',
children: [
{
id: 2,
name: '子节点 1',
children: [
{
id: 4,
name: '子节点 1.1',
children: [
{
id: 7,
name: '子节点 1.1.1'
}
]
},
{
id: 5,
name: '子节点 1.2'
}
]
},
{
id: 3,
name: '子节点 2'
},
{
id: 6,
name: '子节点 3'
}
]
}
]
filterTree(treeList, { name: '1' })
/**预期结果:筛选出所有name字段包好'1'的数据
* [
* {
* children: [
* {
* children: [
* {
* children: [],
* id: 7,
* name: '子节点 1.1.1'
* }
* ],
* id: 4,
* name: '子节点 1.1'
* },
* {
* children: [],
* id: 5,
* name: '子节点 1.2'
* }
* ],
* id: 2,
* name: '子节点 1'
* }
* ]
*/
实现:
/**
* 根据关键字过滤树形结构
* @param treeList 树形结构
* @param filter 过滤条件 如:{ name: 'test' }, 表示根据name字段筛选,可传多个字段
* @param result 过滤结果
* */
export function filterTree(treeList: any[], filter: Record<string, string>, result = []): any[] {
if (!treeList) return []
if (!filter || !Object.keys(filter).length || Object.values(filter).every((item) => !item)) return treeList
for (const node of treeList) {
// 只要有一个属性不匹配就视为失败
const no = Object.keys(filter).some((key) => {
if (typeof filter[key] === 'string') {
// 字符串类型的模糊匹配
return !node[key].toLowerCase().includes(filter[key].toLowerCase())
} else {
// 其他类型的精确匹配
return node[key] !== filter[key]
}
})
if (!no) {
const cloneNode = { ...node, children: [] }
result.push(cloneNode)
if (node.children) {
filterTree(node.children, filter, cloneNode.children)
}
} else {
if (node.children) {
filterTree(node.children, filter, result)
}
}
}
return result
}