递归操作,然后跳出循环

时间:2018-12-11 17:19:18

标签: javascript angularjs angular typescript

我有一个存储部门层次结构的对象。每个部门也可能有子部门。我试图循环检查所有部门,并且子(子)部门的属性均为Open

但是,每当我遇到递归调用时,即使仍有一些项尚未在循环中进行检查,它也只会迭代一次并直接跳转到return true

validateDepartment(departmentHierarchy: any) {
      for (let dept of departmentHierarchy.children) {
          if (dept!= undefined && dept!= null) {
            if (dept.instance.status == "Open")
            {
              continue
            }
            else
            {
                if (dept.children != undefined && dept.children != null) {
                    this.validateDepartment(dept);
                }
                else {
                    return false
                }
            }
          }
      }
      return true
  }

2 个答案:

答案 0 :(得分:0)

这不是任何答案的一部分,但是仅写“做”事情的代码会有所帮助,而不是编写很多执行“无论如何代码已经做过的事情”的代码,例如调用continue当迭代代码是单个if / else时。我们可以以此来重写您的代码,并使其更易于使用:

validateDepartment(tree: any) {
  // step 1: do any validation of the top node
  if (!validateTopNodeOnly(tree)) {
    // this is a stop condition.
    return false;
  }

  if (!tree.children) {
    // this is also a stop condition, but for a different reason.
    // a department without children should not _necessarily_ be invalid.
    return true? return false? probably return true since the node itself is fine.
  }

  if (tree.instance && tree.instance.status !== "open") {
    // and this is a third  condition, but for yet another reason.
    // I'm guessing this is also not "invalid", just means we shouldn't recurse.
    return true? return false? probably return true as well.
  }

  // Then, get all (non-falsey) children,
  let children = tree.children.filter(e => e);

  // and iterate over them:
  for (let e of children) {
    let result = this.validateDepartment(e);

    // cut your run short if validation fails
    if (result === false) {
      return false;
    }
  }

  // and this is the expected stop condition for a normal run.
  return true;
}

但是使用true / false真是天真,并且不会告诉您有关哪里验证失败的信息,因此您通常希望通过“返回失败”来处理“失败的原因”。实际的“正在验证的东西”,因此,如果您的函数返回true,一切都很好,并且返回了!== true,那么您知道它失败了,并且返回的东西是发生错误的部门

还要注意,通过使用早期的验证失败返回,您会丢失信息:相反,最好使用.map()并构造一个通过/未通过验证的所有部门的运行总计,以便您返回一个数组,其中result.every(e => (e===true))为true或为false,在这种情况下result.filter(e => (e!==true))为您提供每个失败部门的集合。

答案 1 :(得分:0)

  isopen = this.validateDepartment(this.departmentHierarchy);

  validateDepartment(dept: any): boolean {
    let result=(dept.instance.status == "Open");
    if (result) {
      if (dept.children) {
        dept.children.forEach(x => {
          result = result && this.validateDepartment(x)
        })
      }
    }
    return result;
  }