Объясните пожалуйста рекурсию в данном примере!
Объясните пожалуйста, зачем второй цикл. Если без него, то в res попадают просто массивы, но по моей логике, там должны оказаться значения. При этом если это не массив, а к примеру res изначально будет строкой, то туда попадают именно значения, как на втором примере. У меня руки опускаются.
let a = [[[2]], [2], [[3]], [4]];
function flatten(array) {
const res = [];
for (let i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
const flat = flatten(array[i]);
for (let j = 0; j < flat.length; j++) {
res.push(flat[j]);
}
} else {
res.push(array[i]);
}
}
return res;
}
console.log(flatten(a));
let a = [[[2]], [2], [[3]], [4]];
function fn(arg) {
let res = '';
for (let i = 0; i < arg.length; i++) {
if (Array.isArray(arg[i])) {
let y = fn(arg[i]);
res+=(y);
} else {
res+=(arg[i]);
}
}
return res;
}
console.log(fn(a));
Ответы (1 шт):
Я попытаюсь: Для удобства пометил цифрами разные этапы рекрусии
function flatten(array) {
const res = [];
for (let i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) { (1)
const flat = flatten(array[i]); (2)
for (let j = 0; j < flat.length; j++) {
res.push(flat[j]); (3)
}
} else {
res.push(array[i]); (4)
}
}
return res; (5)
}
У нас есть массив с элементам:
let a = [[[2, 3, 7]], [2], [[3]], [4]];
Допустим, что мы идем по рекурсии и спускаемся вниз. И вот мы дошли до массива [[2, 3, 7]].
Идя по функции мы проходим по пути 1 - 2 - 3 - 5.
Рассмотрим путь 1 - 2 - 3 подробнее, чтоб разобраться зачем нам еще один цикл:
- (1) Проверяем
[[2, 3, 7]], что внутри массива находится еще один массив[2, 3, 7]. - (2) Запускаем новую функцию (При каждой инициализации у нас создается новый, ПУСТОЙ массив
res).- (1) проверяем, что
[2, 3, 7]каждый из элементов массива не является вложенным массивом. - (4) в массив
resпихаем все элементы из[2, 3, 7]. Т.е. вернется нам массив[2, 3, 7]**
- (1) проверяем, что
- (3) Мы перебираем вернувшийся массив
[2, 3, 7]и точно также пихаем все его элементы вres. Тут важно отметить, что мы вернулись назад и поднялись на одну ступень вверх и в массивеresуже могут быть другие элементы, кроме тех, что мы в него добавляем. А теперь давайте вспомним, что изначальный массив[[2, 3, 7]]был частью другого массива. Зачем нужен второй цикл? Да чтоб если у нас на месте элемента в массиве оказался еще один массив, мы бы его по элементу запихали вres, и продолжили вresдобавлять другие элементы, не являющиеся массивом.
Почему во втором примере такого нет?
Потому что в первом примере нам возвращается массив элементов [2, 3 ,7], и мы его перебираем по одному и добавляем в итоговый.
Во втором примере строка, ее перебирать не нужно и достаточно использовать сложение.
Если хотите сделать первый вариант похожим на второй со строкой, то можете использовать spread оператор:
let a = [[[2]], [2], [[3]], [4]];
function flatten(array) {
const res = [];
for (let i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
const flat = flatten(array[i]);
res.push(...flat);
} else {
res.push(array[i]);
}
}
return res;
}
console.log(flatten(a));