Для каждого разрыва цикла перед завершением массива

У меня простая функция смотрит на объект в массиве. Если он не находит соответствия на основе свойства, он проверяет, есть ли у него дочерние элементы, а затем проверяет каждое из них на предмет значения свойства.

Кажется, что он работает, как и ожидалось, через первый объект с дочерними элементами, однако он не попадает в этот третий слой.

Объект выглядит примерно так:

 data = [{
    title: 'Home',
    route: '/reports/home',
  },
  {
   title: 'Layer 2',
   children: [
     { title: 'Title 1', route: '/reports/title1' },
     { title: 'Title 2', route: '/reports/title2' },
   ],
  },
  {
    title: 'Layer 3',
    children: [
      { title: 'Title 3', route: '/reports/title3' },
      { title: 'Title 4', route: '/reports/title4' },
    ],
  }];


lookUpTitle = navGroup => {
  for (let item of navGroup) {
    if (item.route && item.route.toLowerCase() === '/reports/title3') {
      console.log(item.title)
      return item.title;
    } else {
      if (item.children) {
        return this.lookUpTitle(item.children);
      }
    }
  }
};
    
lookUpTitle(data)

Я просто вызываю функцию и передаю массив, как указано выше.

Я могу найти заголовок 2 очень хорошо, но функция не будет проходить по третьему объекту в массиве, если я ищу заголовок 3 или 4. Чего мне не хватает?

3 ответа

Решение

Что происходит

Чтобы понять, почему цикл останавливается, напишем, что происходит, шаг за шагом:

  1. item принимает значение первого объекта. (Название = Главная).
  2. if условие не выполнено и item не содержит children
  3. item принимает значение второго объекта.
  4. if условие не выполнено но item содержит children
  5. Функция возвращает результат вызова функции lookUpTitle() таким образом цикл останавливается.
  6. Вернитесь к шагу 1, но с дочерними значениями вашего второго объекта.

Таким образом, цикл всегда останавливается, если объект не соответствует if состояние и содержит children,

Как это исправить

Чтобы это исправить, мы должны отслеживать рекурсивные результаты. Проверьте, найден ли результат посредством рекурсивного вызова lookUpTitle(), Если нет, продолжайте цикл, если найден, вы можете вернуть его. Этот метод предполагает, что вам нужен только первый найденный результат, а не все существующие.

lookUpTitle = navGroup => {
  for (let item of navGroup) {
    if (item.route && item.route.toLowerCase() === '/reports/title3') {
      return item.title;
    } else {
      if (item.children) {
        var res = this.lookUpTitle(item.children);
        if(res != undefined)
          return res;
      }
    }
  }
};

Есть проблема, которая из-за return

         if (item.children) {
            //from here it will come out as its return 
             return this.lookUpTitle(item.children);
          }

попробуй вот так

lookUpTitle = navGroup => {
      const title =[];
      for (let item of navGroup) {
        if (item.route && item.route.toLowerCase() === '/reports/title3') {
          console.log(item.title)
          return item.title;
        } else {
          if (item.children) {
            this.lookUpTitle(item.children);
          } else {
            console.log(item.title);
            return item.title;
          }
        }
      }
    };

Если цикл for выполняет итерацию через элемент, у которого есть дочерние элементы (как и во втором), он всегда будет возвращать значение, выходя из цикла for.

Для предложения else необходимо проверить, действительно ли lookUpTitle нашел нужный заголовок. Если это так, верните его, если нет, продолжите цикл for.

Другие вопросы по тегам