如何在保留过滤掉的 parents 的后代的同时过滤树结构?

How to filter a tree structure while keeping the decendants of the parents that are filtered out?

所以我有以下树结构:

const tree = {
  id: "1",
  tag: "pending",
  subtasks: [
    { id: "2", tag: "pending", subtasks: [] },
    {
      id: "3",
      tag: "in progress",
      subtasks: [
        {
          id: "4",
          tag: "pending",
          subtasks: [
            {
              id: "6",
              tag: "in progress",
              subtasks: [
                {
                  id: "10",
                  tag: "pending",
                  subtasks: [{ id: "11", tag: "complete", subtasks: [] }]
                }
              ]
            },
            { id: "7", tag: "complete", subtasks: [] }
          ]
        },
        { id: "5", tag: "pending", subtasks: [] }
      ]
    },
    { id: "4", tag: "complete", subtasks: [] }
  ]
};

并且我想删除任何具有“进行中”tag 的节点。但是,如果它们的 tag 不是“进行中”,我也想保留已删除节点的 children。它们将通过将它们移动到与 parent.

相同的深度和索引级别来保留。

因此,结果将如下所示:

const filteredTree = {
  id: "1",
  tag: "pending",
  subtasks: [
    { id: "2", tag: "pending", subtasks: [] },
    {
      id: "4",
      tag: "pending",
      subtasks: [
        {
          id: "10",
          tag: "pending",
          subtasks: [{ id: "11", tag: "complete", subtasks: [] }]
        },
        { id: "7", tag: "complete", subtasks: [] }
      ]
    },
    { id: "5", tag: "pending", subtasks: [] },
    { id: "4", tag: "complete", subtasks: [] }
  ]
};

我怎样才能做到这一点?

您可以通过勾选 tag 来删除并获取过滤后的 subtasks 或过滤后的新对象 subtasks.

const
    remove = tag => ({ subtasks, ...node }) => {
        subtasks = subtasks.flatMap(remove(tag));
        return node.tag === tag
            ? subtasks
            : [{ ...node, subtasks }]
    },
    tree = { id: "1", tag: "pending", subtasks: [ { id: "2", tag: "pending", subtasks: [] }, { id: "3", tag: "in progress", subtasks: [{ id: "4", tag: "pending", subtasks: [{ id: "6", tag: "in progress", subtasks: [{ id: "10", tag: "pending", subtasks: [{ id: "11", tag: "complete", subtasks: [] }] }] }, { id: "7", tag: "complete", subtasks: [] }] }, { id: "5", tag: "pending", subtasks: [] }] }, { id: "4", tag: "complete", subtasks: [] }] },
    result = remove('in progress')(tree);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }