遍历树结构返回符合条件的元素

[
        {
            name: '泵站',
            id: 'bengzhan',
            isGet: false,
            children: []
        },
        {
            name: '泵站',
            id: 'bengzhan',
            isGet: false,
            children: []
        },
        {
            name: '闸站',
            id: 'zhazhan',
            isGet: false,
            children: [
                {
                    ame: '闸站1',
                    id: 'zhazhan1',
                    isGet: true,
                    children: []
                },
                {
                    name: '闸站2',
                    id: 'zhazhan2',
                    isGet: true,
                    children: [
                        {
                            name: '闸站21',
                            id: 'zhazhan21',
                            isGet: true,
                            children: []
                        },
                        {
                            name: '闸站22',
                            id: 'zhazhan22',
                            isGet: true,
                            children: []
                        },
                    ]
                },
                {
                    name: '闸站3',
                    id: 'zhazhan3',
                    isGet: true,
                    children: [
                        {
                            name: '闸站31',
                            id: 'zhazhan31',
                            isGet: true,
                            children: []
                        },
                        {
                            name: '闸站32',
                            id: 'zhazhan32',
                            isGet: true,
                            children: []
                        },
                    ]
                },
            ]
        },
    ]

遍历这样的树结构,想要这样的结果

arr = [
                {
                    ame: '闸站1',
                    id: 'zhazhan1',
                    isGet: true,
                    children: []
                },
                {
                    name: '闸站2',
                    id: 'zhazhan2',
                    isGet: true,
                    children: [
                        {
                            name: '闸站21',
                            id: 'zhazhan21',
                            isGet: true,
                            children: []
                        },
                        {
                            name: '闸站22',
                            id: 'zhazhan22',
                            isGet: true,
                            children: []
                        },
                    ]
                },
                {
                    name: '闸站3',
                    id: 'zhazhan3',
                    isGet: true,
                    children: [
                        {
                            name: '闸站31',
                            id: 'zhazhan31',
                            isGet: true,
                            children: []
                        },
                        {
                            name: '闸站32',
                            id: 'zhazhan32',
                            isGet: true,
                            children: []
                        },
                    ]
                },
            ]
阅读 2.9k
2 个回答

楼上的文章看了一下,好像是不符合条件的直接裁剪了,没管子节点。但是这个问题是如果某个节点不满足条件,就删除节点本身,但是提升其子节点。这里关键点是提升了之后,相当于是改变了树本身。
提升子节点这个需求单向树不太好完成,所以要加个父节点的缓存,保存每个节点对应父节点的指向。而且子节点提升了一层,想要遍历到而且不乱的话,应该用层次遍历.代码如下:

const traverseByGrade = (root, visit) => {
  const checkRoot = { children: [].concat(root) };
  let checkItems = [checkRoot];
  const parentCache = new WeakMap();
  while (checkItems.length) {
    const checkItem = checkItems.shift();
    const children = checkItem.children || [];
    let tempParent = checkItem;
    if (checkItem !== checkRoot) {
      const info = visit(checkItem, parentCache, checkItems);
      if (info) {
        tempParent = info.parent;
        checkItems = info.checkItems;
      }
    }
    children.forEach((it) => {
      parentCache.set(it, tempParent);
    });
    checkItems = checkItems.concat(children);
  }
  return checkRoot.children;
};

const pruneTree = (root, validateFunc = () => true) => {
  const checkValidateAndPrune = (node) => {
    if (!node) return false;
    const children = node.children
      .map((n) => {
        if (checkValidateAndPrune(n)) return n;
        return null;
      })
      .filter(Boolean);
    node.children = children;
    return !!node.children.length || validateFunc(node);
  };
  return checkValidateAndPrune(root) ? root : null;
};

const filterNodes = (nodes) => {
  const visit = (node, parentCache, checkItems) => {
    if (!node.isGet) {
      const parent = parentCache.get(node);
      const children = node.children || [];
      node.children = [];
      parent.children = children.concat(parent.children || []);
      return {
        parent,
        checkItems: children.concat(checkItems),
      };
    }
    return null;
  };
  const children = traverseByGrade(nodes, visit);
  const root = { isGet: true, children };
  pruneTree(root, (node) => node.isGet);
  return root.children;
};

traverseByGradepruneTree是公共方法,分别用于层次遍历和裁剪树
你直接调用filterNodes方法就行
测试结果::
image.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题