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

// 测试数据
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"));
阅读 2k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏