#javascript #arrays #recursion #nested
#javascript #массивы #рекурсия #вложенный
Вопрос:
Я пытаюсь преобразовать этот вложенный массив в плоский массив. При использовании этого способа решения кажется, что каждый раз, когда я вызываю arrayFlattener (элемент), newArr становится пустым массивом. Кто-нибудь может мне помочь с этим? Спасибо.
const arrayFlattener = (arr) => {
let newArr = [];
for (let i = 0; i < arr.length; i ) {
let element = arr[i];
if (Array.isArray(element)){
newArr.push(arrayFlattener(element));
} else {
newArr.push(element);
}
}
return newArr;
}
console.log(arrayFlattener(['I', 'am', 'working', ['on', 'another', 'level']]));
Комментарии:
1. Было бы полезно, если бы вы отметили этот вопрос языком, на котором работаете. (Я бы сделал это за вас, но я не узнаю синтаксис.)
2. Является ли производительность требованием для использования рекурсии?
3. Вы ищете общую рекурсию, хвостовую рекурсию или итеративную рекурсию?
Ответ №1:
flat
выполните работу с depth
param
уровнем, указывающим, насколько глубоко структура вложенного массива должна быть сглажена.
Пример
const arr = ['I', 'am', 'working', ['on', 'another', 'level'], 'now', ["now", ["hello", "you you"]]]
console.log(arr.flat(2))
Ответ №2:
Ваш код и теория в порядке. Вы просто выбрали неправильный метод. Используйте concat
вместо push
(чтобы расширить результат, а не вставлять в него):
const arrayFlattener = (arr) => {
let newArr = [];
for (let i = 0; i < arr.length; i ) {
let element = arr[i];
if (Array.isArray(element)){
newArr = newArr.concat(arrayFlattener(element));
} else {
newArr.push(element);
}
}
return newArr;
}
console.log(arrayFlattener(['I', 'am', 'working', ['on', 'another', 'level']]));
Ответ №3:
Вы можете использовать flatMap
let newArr = ['I', 'am', 'working', ['on', 'another', 'level']].flatMap(el=>el);
console.log(newArr);
или используйте flat
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); // depth argument to flatten the array
// [1, 2, 3, 4, 5, 6]
Комментарии:
1. Я согласен, если вам нужно реализовать рекурсию, вы можете сделать так, как ответил @Andreas, но также я считаю, что реализация браузера будет быстрее, чем реализация рекурсии.
Ответ №4:
В настоящее время ваша функция не выравнивает массив, а просто выполняет синтаксический анализ по каждому отдельному элементу массива. Он по-прежнему возвращает ту же структуру массива.
Чтобы сгладить массив, вы также должны передать результирующий массив, чтобы отдельный элемент можно было поместить прямо в результирующий массив вместо создания другого массива и отправки его в результирующий массив (который создает ту же исходную структуру массива)
let newArr = [];
const arrayFlattener = (arr, result) => {
for (let i = 0; i < arr.length; i ) {
let element = arr[i];
if (Array.isArray(element)){
result = arrayFlattener(element, result);
} else {
result.push(element);
}
}
return result
}
console.log(arrayFlattener(['I', 'am', 'working', ['on', 'another', 'level'], 'now'], newArr));
Комментарии:
1. Почему бы не использовать flattenMap?
2. Это кажется немного странным. Я думаю, что более распространено вводить просто входные данные и ожидать результата, а не вводить одновременно входные данные и указатель на результат, если только последнее не является абсолютно необходимым.
Ответ №5:
Вот три решения
Вы можете использовать .flatMap
и рекурсию или
const flatten = (xs) =>
Array.isArray(xs) ? xs.flatMap(flatten) : [xs]
const array = ['I', 'am', 'working', ['on', 'another', ['level']]]
console.log(flatten(array))
вы можете использовать .reduce
и рекурсию
const flatten = (xs) =>
xs.reduce(
(y, x) => y.concat(Array.isArray(x) ? flatten(x) : [x]),
[])
const array = ['I', 'am', 'working', ['on', 'another', ['level']]]
console.log(flatten(array))
или еще лучше просто использовать .flat
const flatten = (xs) =>
xs.flat(Infinity)
const array = ['I', 'am', 'working', ['on', 'another', ['level']]]
console.log(flatten(array))