【问题标题】:Recursive Operation and then jump out of the loop递归操作然后跳出循环
【发布时间】:2018-12-11 17:19:17
【问题描述】:

我有一个存储部门层次结构的对象。每个部门也可能有子部门。我正在尝试循环检查所有部门以及子(子)部门属性是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
  }

【问题讨论】:

  • 能否提供departmentHierarchy的结构,departmentHierarchy.departmentdepartmentHierarchy一样吗?如果不是,那可能是导致问题的原因。
  • @GetOffMyLawn,抱歉,在阅读您的评论后代码中出现了拼写错误。我已经修好了。你能再检查一下吗?
  • 看起来您只是在递归调用之前忘记了return,但是...在其中“执行”任何操作的实际代码在哪里?通常,您希望返回某种结果,告诉您在树中的哪一件事以及验证失败(如果有的话)。

标签: javascript angularjs angular typescript


【解决方案1】:

不是任何答案的一部分,但它有助于只编写“做”事情的代码,而不是编写大量代码来做“代码无论如何都会做的事情”,例如调用 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 非常幼稚,并且不会告诉您任何关于 where 验证失败的信息,因此您需要处理“失败的原因”,通常是通过返回对实际的“正在验证的东西”,所以如果你的函数返回 true,一切都很好,它返回 !== true,那么你知道它失败了,它返回的东西是出现问题的部门。

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

【讨论】:

    【解决方案2】:
      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;
      }
    

    【讨论】:

      猜你喜欢
      • 2021-04-09
      • 2012-04-03
      • 1970-01-01
      • 2016-04-08
      • 1970-01-01
      • 2011-03-21
      • 2012-06-09
      • 2018-06-27
      • 2017-01-21
      相关资源
      最近更新 更多