递归检查树上的条件并在找到时停止

时间:2017-09-13 11:21:52

标签: javascript typescript recursion tree

我有一个这样的基本树数据结构(忘记缺少的父属性):

data = { 
  name: 'root', 
  value: 20,
  children: [
    {
      name: 'child_1',
      value: 12,
      children: [...]
    },
    {
      name: 'child_2',
      value: 8,
      children: [...]
    },
    ]  
}

我想编写一个函数,它接收任何项目,可以是root或任何子项,并对其进行一些评估。

如下所示:

public doCheck(item: TreeItem): boolean {

    item.children.forEach( (i: TreeItem) => {
      return this.doCheck(i);
    });

    return (item.children.some( (i: TreeItem) => i.value >= 10));
}

但是,现在这似乎正在遍历树,但只返回评估(item.children.some( (i: TreeItem) => i.value >= 10)),就像它仅在根项上调用一样,对于它永远不会是真的。

我哪里错了?

2 个答案:

答案 0 :(得分:2)

您希望摆脱forEach,而是递归some

我将假设value出现在儿童的条目中。如果是这样的话:

function doCheck(item) {
    // If `children` is optional, you could add
    // `item.children &&` just after `return`
    return item.children.some(entry => entry.value >= 10 || doCheck(entry));
}

console.log(doCheck(data)); // true or false

var data = { 
  name: 'root', 
  data: [],
  value: 5,
  children: [
    {
      name: 'child_1',
      data: [],
      children: [],
      value: 10,
    },
    {
      name: 'child_2',
      data: [],
      children: [],
      value: 20
    },
    ]  
};

function doCheck(item) {
    // If `children` is optional, you could add
    // `item.children &&` just after `return`
    return item.children.some(entry => entry.value >= 10 || doCheck(entry));
}

console.log(doCheck(data)); // true, since `child_1` has it

您需要添加类型注释等,以将其转换回TypeScript。

如果你想找到条目,而不仅仅是检查它,你可以使用find代替some

function doCheck(item) {
    // If `children` is optional, you could add
    // `item.children &&` just after `return`
    return item.children.find(entry => entry.value >= 10 || doCheck(entry));
}

console.log(doCheck(data)); // undefined, or the child

var data = { 
  name: 'root', 
  data: [],
  value: 5,
  children: [
    {
      name: 'child_1',
      data: [],
      children: [],
      value: 10,
    },
    {
      name: 'child_2',
      data: [],
      children: [],
      value: 20
    },
    ]  
};

function doCheck(item) {
    // If `children` is optional, you could add
    // `item.children &&` just after `return`
    return item.children.find(entry => entry.value >= 10 || doCheck(entry));
}

console.log(doCheck(data).name);// "child_1"

答案 1 :(得分:0)

不清楚你究竟想做什么,但这一部分:

item.children.forEach( (i: TreeItem) => {
    return this.doCheck(i);
});

没什么意义,因为你基本上没有在这里做任何事情 你可能正在寻找这个:

public doCheck(item: TreeItem): boolean {
    return 
        item.children.some(i => i.value >= 10)
        &&
        item.children.some(i => this.doCheck(i));
}

可能是||而不是&&

当然可以改为:

public doCheck(item: TreeItem): boolean {
    return item.children.some(i => i.value >= 10 && this.doCheck(i));
}