将一个数据库条目过滤id为指定树
需求
- 自下向上的多条树形结构数据,反转合并成一条或多条自上向下树形结构
- 已知多个数据的id,得出所有的上级,之后再反转
- 原始数据 规则:每条数据的pid是唯一的
arr = [{id:1,pid:0},
{id:2,pid:1},
{id:3,pid:2},
{id:4,pid:3},
{id:5,pid:3},
{id:6,pid:2},
{id:7,pid:1}]
已知 id为3,7过滤,需要得到结果为
3->2->1->0
7->1->0
[
{
id:1,
pid:0,
children:[
{
id:2,
pid:1,
children:[
{
{id:3,pid:2}
}
]
},
{
id:7,
pid:1
}
]
}
]
思路
- 根据数据源构建树结构,每个节点只有一个父节点,换而言之遍历单向给当前节点添加符合条件子节点
- 节点数据修改需要找到指定嵌套子节点位置,同时去掉它的子节点,以及它的同父的兄弟节点
代码
// 1.得到数据源副本
nda = arr.map(v => {
return { ...v }
})
// 2.建立父子节点关系链
nda.forEach(v => {
// 找出前节点的子节点
v.children = nda.filter(child => child.pid == v.id)
// 裁剪叶子节点
v.children == 0 && delete v.children
});
function filterTree(nd, ids) {
// 1.裁剪过滤id指向的节点 使其为叶子节点
if (ids.includes(nd.id)) {
nd.children && delete nd.children
}
if (nd.children) {
for (let i = nd.children.length - 1; i >= 0; i--) {
const element = nd.children[i];
// 2.回调之前需要先判断是否有下级
if (element.children) {
// 3. 移动指针进入下一层
filterTree(element, ids)
} else {
// 4.裁剪同父兄弟节点数据,顺序不可颠倒
if (!(ids.includes(element.id))) {
nd.children.splice(i, 1)
}
}
}
}
return
}
测试
let root = nda.find(item => item.id == 1)
filterTree(root, [3, 7])
console.log(JSON.stringify(root, null, 2))
小结
- 修改之前先查找
- 嵌套递归