首页 > 解决方案 > 如何按属性修改树对象?

问题描述

我有一个类型的对象:

export interface TreeNode extends ITreeNode {
   name: string,
   children:  TreeNode[],
   show?: boolean;
}

我需要通过属性来减少这个对象show并返回一个新的树,其中showtrueundefined

我试过这个:

  function prepareNodes(source: TreeNode) {
        if (source.show!== undefined || source.show == false) delete source;
      if (source.children) {
        source.children.forEach((child: TreeNode) => {
          this.prepareNodes(child);
        });
      }
  }

我也试过:

function prepareNodes(source: any) {
      if (source.show !== undefined && source.show === false) source = null;
      if (source.children) {
        source.children = source.children.filter((child: any) => child.show== undefined || child.show === true);
        source.children.forEach((child: any) => prepareNodes(child));
      }
  }

标签: javascripttypescript

解决方案


目前我的假设是,您希望生成一棵新树,其中仅包含原始树的那些节点,其中该节点的show属性为trueor 或undefined为该节点和所有祖先节点。因此,如果show在任何节点上为假,则输出树将不包含该节点或该节点的任何子树。

我还假设根节点可能有showfalse在这种情况下,整个树可能会结束undefined。您不能设置修改对象成为undefined;您可以更改其内容,但不能删除它。所以我不会介绍任何试图修改原始树的东西。我不会碰原来的树。相反,我将生成一棵全新的树。

开始:

const defined = <T,>(x: T | undefined): x is T => typeof x !== "undefined";

function filterTree(source: TreeNode): TreeNode | undefined {
  if (source.show === false) return;
  return {
    name: source.name,
    show: source.show,
    children: source.children.map(filterTree).filter(defined)
  }
}

如果参数节点的属性恰好是(而不是) ,则该filterTree()函数将返回。否则,它会生成一个具有相同and的新节点,其属性是您在每个原始节点上调用(递归)然后输出任何节点时获得的属性。undefinedshowfalseundefinednameshowchildrenfilterTree()childrenfilterundefined

我正在使用一个用户定义的类型保护函数,调用该函数defined让编译器知道filtering 需要一个数组 TreeNode | undefined并生成一个数组TreeNode,从而消除任何undefined条目。

希望这符合您的用例;请根据您拥有的任何数据进行测试并检查,因为不幸的是问题不包括此类数据。

Playground 代码链接


推荐阅读