通过将未通过测试的树节点映射到其子节点来修剪树

时间:2019-03-14 18:48:53

标签: javascript algorithm

我的问题是建立在another problem I was trying to solve and received an excellent answer for上,那里有一棵树:

const treeData = [{
  title: '0-0',
  key: '0-0',
  children: [{
    title: '0-0-0',
    key: '0-0-0',
    children: [
      { title: '0-0-0-0', key: '0-0-0-0', children: [] },
      { title: '0-0-0-1', key: '0-0-0-1', children: [] },
      { title: '0-0-0-2', key: '0-0-0-2', children: [] },
    ],
  }, {
    title: '0-0-1',
    key: '0-0-1',
    children: [
      { title: '0-0-1-0', key: '0-0-1-0', children: [] },
      { title: '0-0-1-1', key: '0-0-1-1', children: [] },
      { title: '0-0-1-2', key: '0-0-1-2', children: [] },
    ],
  }, {
    title: '0-0-2',
    key: '0-0-2',
    children: []
  }],
}, {
  title: '0-1',
  key: '0-1',
  children: [
    { title: '0-1-0-0', key: '0-1-0-0', children: [] },
    { title: '0-1-0-1', key: '0-1-0-1', children: [] },
    { title: '0-1-0-2', key: '0-1-0-2', children: [] },
  ],
}, {
  title: '0-2',
  key: '0-2',
  children: []
}];

和一组叶节点:

const leafNodes = ['0-0-1-2', '0-1-0-1', '0-1-0-2']

之前,我只想要过滤/修剪的树副本,其中包含到叶子节点的所有路径,但是现在,我想通过删除不满足测试要求的父节点来进一步修剪它-测试其所有子项都包含在叶节点列表中。生成的树看起来像这样:

const pruned = [{
    title: '0-0-1-2',
    key: '0-0-1-2',
    children: []
  },
  {
    title: '0-1-0-1',
    key: '0-1-0-1',
    children: []
  }, {
    title: '0-1-0-2',
    key: '0-1-0-2',
    children: []
  }
]

此处,具有键0-0-1的节点将被删除,因为它的3个子节点(0-0-1-2)中只有一个包含在leafNodes列表中,而子节点包含在叶节点列表中(在在这种情况下,只有一个)被提升到现在已删除的父级的水平。由于没有将所有 个子级包含在修剪的树中,因此这将流回到已删除节点的父级,现在使用键0-0

相同的模式也适用于0-1

1 个答案:

答案 0 :(得分:1)

您可以迭代该数组并检查是否完全选择了子节点,然后获取实际节点或仅某些子节点,然后仅获取这些子节点。

function getShort(array, keys) {
    var result = [],
        every = true;

    array.forEach(o => {
        var children;

        if (keys.includes(o.key)) return result.push(o);
        if (!o.children || !o.children.length) return every = false;

        children = getShort(o.children, keys);
        if (children.length && children.length === o.children.length) return result.push(o);

        result.push(...children);
        every = false;
    });

    return every
        ? array
        : result;
}

const
    treeData = [{ key: '0-0', children: [{ key: '0-0-0', children: [{ key: '0-0-0-0', children: [] }, { key: '0-0-0-1', children: [] }, { key: '0-0-0-2', children: [] }] }, { key: '0-0-1', children: [{ key: '0-0-1-0', children: [] }, { key: '0-0-1-1', children: [] }, { key: '0-0-1-2', children: [] }] }, { key: '0-0-2', children: [] }] }, { key: '0-1', children: [{ key: '0-1-0-0', children: [] }, { key: '0-1-0-1', children: [] }, { key: '0-1-0-2', children: [] }] }, { key: '0-2', children: [] }],
    leafNodes = [
        '0-0-0-0', '0-0-0-1', '0-0-0-2', // all 0-0-0 all 0-0
        '0-0-1-0', '0-0-1-1', '0-0-1-2', // all 0-0-1 all 0-0
        '0-0-2',                         // all 0-0-2 all 0-0
        '0-1-0-1', '0-1-0-2'
    ],
    short = getShort(treeData, leafNodes);

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