1

我有一个选定的数组

this.selectedArray = ["1:Tree", "2:PT", "5:PT - DD", "11:PT - C", "3:SAC", "7:SAC - DR", "6:SAC - DDE"]

和带有孩子的树结构:

this.root =    
{"children": [
   {"children": [
     {
      "children": [],
      "id": 12,
      "name": "PT - D"
    },
    {
      "children": [
        {
          "children": [],
          "id": 8,
          "name": "PT-33"
        },
        {
          "children": [],
          "id": 10,
          "name": "PT-62"
        },
        {
          "children": [],
          "id": 9,
          "name": "PT-52"
        }
      ],
      "id": 4,
      "name": "PT - 32"
    },
    {
      "children": [
        {
          "children": [],
          "id": 11,
          "name": "PT - C"
        }
      ],
      "id": 5,
      "name": "PT - DD"
    }
  ],
  "id": 2,
  "name": "PT"
},
{
  "children": [
    {
      "children": [],
      "id": 7,
      "name": "SAC - DR"
    },
    {
      "children": [],
      "id": 6,
      "name": "SAC - DE"
    }
  ],
  "id": 3,
  "name": "SAC"
}
],
 "id": 1,
 "name": "Tree"
}

如果 node.Id + ':' + node.name 与 this.selectedArray 中的任何项目都不匹配,我想从树中删除该节点。

我无法找到一种算法,该算法允许我从深度嵌套的树中删除与 this.selected 中的任何项目不匹配的所有对象数据。

这是代码:

 setSearchResult(selectedArray) {
    if (!!selected) {
        let this.tree = JSON.parse(JSON.stringify(this.root));
        this.topLevelGroups = this.removeFromTree(this.tree, selectedArray, null, null);
    }
}

removeFromTree(parent, selectedArray, grandParent, idx) {
    let { name, id, children } = parent;
    let parentId = id + ':' + name;
    if (!!selectedArray) {
        if (!selectedArray.includes(parentId)) {
            if (grandParent) {
                grandParent.children.splice(idx, 1);
            } 
            else return null;
        }
        if (!!parent && !!children) {
            for (let i = 0; i < children.length; i++) {
                this.removeFromTree(children[i], selectedArray, parent, i);
            }
        }
    }
    return this.tree.children;
  }

我认为问题在于执行具有 this.slice 的代码后,它会返回并且不会转到其兄弟。对此有何建议?

4

2 回答 2

1

您可以采用非变异方法并通过尊重孩子来减少数组。

该解决方案将所需的哈希表id作为键并作为数组name拆分值的值。selected

结果只包括已知节点。

const
    filter = (r, { children = [], ...o }) => {
        if (nodes[o.id] !== o.name) return r;
        children = children.reduce(filter, []);
        r.push(children.length ? { ...o, children } : o);
        return r;
    },
    selected = ["1:Tree", "2:PT", "5:PT - DD", "11:PT - C", "3:SAC", "7:SAC - DR", "6:SAC - DDE"],
    nodes = selected.reduce((r, s) => {
        var [k, v] = s.split(':');
        r[k] = v;
        return r;
    }, {}),
    tree = { children: [{ children: [{ children: [], id: 12, name: "PT - D" }, { children: [{ children: [], id: 8, name: "PT-33" }, { children: [], id: 10, name: "PT-62" }, { children: [], id: 9, name: "PT-52" }], id: 4, name: "PT - 32" }, { children: [{ children: [], id: 11, name: "PT - C" }], id: 5, name: "PT - DD" }], id: 2, name: "PT" }, { children: [{ children: [], id: 7, name: "SAC - DR" }, { children: [], id: 6, name: "SAC - DE" }], id: 3, name: "SAC" }], id: 1, name: "Tree" },
    result = tree.children = tree.children.reduce(filter, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

于 2020-02-09T10:13:06.087 回答
1

一个简单的递归过滤函数,因为你在你的字符串中使用selectedArray你可以很容易地Set用来测试一个节点。

const tags = new Set(selectedArray);

function filterArray ({ children, id, name }) {
    const tag = `${id}:${name}`;
    if (tags.has(tag)) {
        return {
            id,
            name,
            children: children.map(filterArray).filter((child) => child !== null)
        };
    }
    return null;
}


const output = filterArray(root);
console.log(JSON.stringify(output, null, 4));
于 2020-02-09T10:04:55.783 回答