javascript 树形结构数据,如何根据叶子节点的属性查询并返回所经路径的新树?

作者站长头像
站长
· 阅读数 8
// 测试数据
let data = [
  {
    type: "A",
    children: [
      {
        type: "B",
        children: [
          {
            type: "C",
            children: [],
          },
          {
            type: "D",
            children: [],
          },
        ],
      },
      {
        type: "C",
        children: [],
      },
      {
        type: "E",
        children: [],
      },
    ],
  },
  {
    type: "F",
    children: [
      {
        type: "C",
        children: [],
      },
      {
        type: "H",
        children: [],
      },
    ],
  },
  {
    type: "C",
    children: [],
  },
  {
    type: "C",
    children: [
      {
        type: "A",
        children: [],
      },
    ],
  },
];

期望结果:

// 查找type为C的子节点(children为空),结果应返回
[
  {
    type: "A",
    children: [
      {
        type: "B",
        children: [
          {
            type: "C",
            children: [],
          },
        ],
      },
      {
        type: "C",
        children: [],
      },
    ],
  },
  {
    type: "F",
    children: [
      {
        type: "C",
        children: [],
      },
    ],
  },
  {
    type: "C",
    children: [],
  },
];

补充

// 这种情况不返回,因为C不是叶子节点
[{
    type: "C",
    children: [
      {
        type: "A",
        children: [],
      },
    ],
  }]

结合边城用户的文章,最后得出的方法:

function findTreeNode(tree, predicate) {
  if (Array.isArray(tree)) {
    return filter(tree) ?? [];
  } else {
    tree.children = filter(tree.children);
    return tree;
  }

  function filter(nodes) {
    if (!nodes?.length) {
      return nodes;
    }

    return nodes.filter((it) => {
      // 先筛选子树,如果子树中没有符合条件的,children 会是 [] 或 undefined
      const children = filter(it.children);
      // 根据当前节点情况和子树筛选结果判断是否保留当前节点
      if ((predicate(it) && !it.children?.length) || children?.length) {
        // 如果要保留,children 应该用筛选出来的那个;不保留的话就不 care 子节点了
        it.children = children;
        return true;
      }
      return false;
    });
  }
}

let data = [
  {
    type: "A",
    children: [
      {
        type: "B",
        children: [
          {
            type: "C",
            children: [],
          },
          {
            type: "D",
            children: [],
          },
        ],
      },
      {
        type: "C",
        children: [],
      },
      {
        type: "E",
        children: [],
      },
    ],
  },
  {
    type: "F",
    children: [
      {
        type: "C",
        children: [],
      },
      {
        type: "H",
        children: [],
      },
    ],
  },
  {
    type: "C",
    children: [],
  },
  {
    type: "C",
    children: [
      {
        type: "A",
        children: [],
      },
    ],
  },
];

console.log(findTreeNode(data, (item) => item.type === "C"));
回复
1个回答
avatar
test
2024-07-03
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容