Рекурсивный перебор массива в JS

Подскажите пожалуйста, как перебрать массив с неизвестной вложенностью? Ситуация такая, практикую js и reactjs на начальном уровне, делаю приложение с покемонами и хочу вывести компонент с эволюцией :). API возвращает такой ого вида объект:

{
  baby_trigger_item: null,
  chain: {
    evolution_details: [],
    evolves_to: [
      {
        evolves_to: [
          {
            evolves_to: [],
            is_baby: false,
            species: {
              name: "poliwrath",
              url: "https://pokeapi.co/api/v2/pokemon-species/62/"
            }
          },
          {
            evolves_to: [],
            is_baby: false,
            species: {
              name: "politoed",
              url: "https://pokeapi.co/api/v2/pokemon-species/186/"
            }
          }
        ],
        is_baby: false,
        species: {
          name: "poliwhirl",
          url: "https://pokeapi.co/api/v2/pokemon-species/61/"
        }
      }
    ],
    is_baby: false,
    species: {
      name: "poliwag",
      url: "https://pokeapi.co/api/v2/pokemon-species/60/"
    }
  },
  id: 26
};

Количество вложенных массивов "evolves_to" может быть много, а может и не быть. а еще внутри "evolves_to" может быть несколько объектов, т.е развитие как бы одного уровня в несколько видов. На выходе должно получиться(думаю такая структура будет удобна в дальнейшей работе):

[
    [
      {
        name: "",
        url: ""
      }
    ],
    [
      {
        name: "",
        url: ""
      },
      {
        name: "",
        url: ""
      }
    ][
      {
        name: "",
        url: ""
      }
    ]
  ]

Т.е первый массив с первым уровнем развития, второй массив второй уровень массива с двумя видами, третий массив соответственно третий уровень и т.д. Если вложенность не известна, то нужно как-то оперировать с рекурсией? копал я в сторону map, reduce...и пытался влепить в них рекурсию... но к сожалению пока не додумался. Если не затруднит 'покажите пусть истинный'. Заранее благодарю )


Ответы (2 шт):

Автор решения: HackerU

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

function printRec(obj, pref=''){
    let string = pref+'->'+obj.species.name; 
    console.log(string)
    if (!obj.evolves_to.length){
        return 
    }
    obj.evolves_to.forEach(elem=>printRec(elem, string))
}
printRec(a.chain)
→ Ссылка
Автор решения: Eugene Kuznetsov

Для решения данной задачи на мой взгляд вам подойдет такой подход, сочетание reduce, concat и немного рекурсии.

Проходясь по массиву с помощью итератора reduce, проверяется является ли текущее значение массивом, если да, то производится рекурсивный вызов функции, если нет, конкатенируем с аккумулирующим значением.

Таким образом, на входе массив неизвестной вложенности, на выходе одномерный массив.

const exampleArr = [1, [1, 2, [3, 4]], [5, 6]];
const toOneLevelArray = (arr) => arr.reduce((accum, currentVal) =>  accum.concat(Array.isArray(currentVal) ? toOneLevelArray(currentVal) : currentVal), []);
console.log(toOneLevelArray(exampleArr));

→ Ссылка