Рекурсивная операция, а затем выпрыгнуть из цикла - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть объект, который хранит иерархию отделов.В каждом отделе также может быть подразделение.Я пытаюсь проверить все отделы, а также свойства дочерних (дочерних) отделов 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 голосов
/ 12 декабря 2018
  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;
  }
0 голосов
/ 11 декабря 2018

Не является частью какого-либо ответа, но это помогает писать только код, который «делает» вещи, вместо того, чтобы иметь много кода, который делает «то, что код уже сделал бы в любом случае», такой как вызов 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)) является истинным, либо ложным, и в этом случае result.filter(e => (e!==true)) дает вам набор для каждого неудачного завершенияотдел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...