Bootstrap

树形结构数据条件过滤

将一个数据库条目过滤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. 根据数据源构建树结构,每个节点只有一个父节点,换而言之遍历单向给当前节点添加符合条件子节点
  2. 节点数据修改需要找到指定嵌套子节点位置,同时去掉它的子节点,以及它的同父的兄弟节点

代码


// 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))

小结

  • 修改之前先查找
  • 嵌套递归
;