前言
树形结构数据的核心操作是遍历,其次由遍历延伸的一些我们常见的业务操作有:
(1)查找/过滤返回符合条件的节点(返回节点数据)
(2)原结构基础上过滤掉符合条件的节点【删除或者说过滤符合/不符合条件节点】(返回树结构)
(3)树形数据重构【原有树形数据基础上,增加自定义属性/修改原有属性】(返回树结构)
对应1、2、3点的实现方法如下(以下方法均不污染源数据):
1.findNode()
(1)源数据
//扒了elementUI树的数据,反正基本的树形结构)
let myTree = [{
id: 1,
label: 'test',
children: [{
id: 4,
label: 'test',
children: [
{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: 'test'
}
]
}]
}, {
id: 2,
label: 'test666',
children: [
{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: 'test666'
}
]
}, {
id: 3,
label: '一级 3',
children: [
{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}
]
}],
(2)预期结果
//查找并返回id为7的节点,并返回该节点数据
{
id: 7,
label: '二级 3-1'
}
(3)方法函数
//--------------核心方法:支持自定义查询条件--------------------
function findNode(tree, func) {
for (const node of tree) {
if (func(node)) return node
if (node.children) {
const res = findNode(node.children, func)
if (res) return res
}
}
return null
}
//--------------调用--------------
let myNodes = findNode(myTree,(node)=>{
return node.id === 7;
})
2.filterTree()
(1)源数据
同上
(2)预期结果
//在源数据的基础上过滤掉所有的label为'test666'的节点(这里根据实际场景,例如节点中包含标记性别的属性gender:0女/1男,可以过滤掉所有属性gender为0或1的节点),并返回一个新的树
[{
id: 2,
label: 'test666',
children: [
{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: 'test666'
}
]
}]
(3)方法函数
//--------------核心方法--------------
function filterTree(tree, func) {
return tree.filter(node => {
return func(node);
}).map(node => {
node = Object.assign({}, node)
if (node.children) {
node.children = filterTree(node.children, func)
}
return node
})
}
//--------------调用--------------
let newTree = filterTree(myTree,(node)=>{
return node.label === 'test';
})
3.mapTree()
(1)源数据
同上
(2)预期结果
//具体结果省略......
//总言之就是给每个节点加上一个新的属性check:true(当然,根据实际业务场景或需求也可以做到对节点的属性值进行修改等等操作)
(3)方法函数
//--------------核心方法--------------
function mapTree(tree, func) {
return tree.map(node => {
node = Object.assign({}, node)
node = func(node)
if (node.children) {
node.children = mapTree(node.children, func)
}
return node
})
}
//--------------调用--------------
let newTree = mapTree(myTree,(node)=>{
return {
...node,
checked:true,
}
})
遍历写法可参考:
https://segmentfault.com/q/1010000040502862/
https://www.cnblogs.com/yanggb/p/12572124.html
https://xie.infoq.cn/article/994044797f1e3c36a2bc796fe
https://www.jb51.net/article/77042.htm