Как свернуть многомерный массив - PullRequest
1 голос
/ 11 октября 2019

Как это сделать?

unpack_array([1, [10, 30, 40,[34,53],4],2]) -> [1,10,30,40,34,53,4,2]

Я знаю, что должна быть применена рекурсия. Я пытался, но, оказывается, работает только в одном направлении.

function unpack_array (arr, acc_arr=[]) {
  if (!arr) return acc_arr;
  let i = 0;
  while (arr[i] && !Array.isArray(arr[i])) {
    acc_arr.push(arr[i++])
  }
  return unpack_array(arr[i], acc_arr)
}

Я считаю, что здесь нужно использовать метод "уменьшить".

Ответы [ 2 ]

5 голосов
/ 11 октября 2019

Метод Array.prototype.flat() будет работать при условии, что вы предоставите ему аргумент Infinity, чтобы гарантировать, что все уровни многомерного массива сглажены:

console.log([1, [10, 30, 40, [34, 53], 4], 2].flat(Infinity))

В качестве альтернативы в связанной документации предлагается рекурсивный метод flatDeep, в котором используются reduce и concat для реализации желаемого поведения:

function flatDeep(arr) {
   return arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val) : val), []);
};

console.log(flatDeep([1, [10, 30, 40, [34, 53], 4], 2]));
2 голосов
/ 11 октября 2019

Простой рекурсивный подход состоит в том, чтобы просто вызвать Array#reduce и использовать Array#concat, чтобы объединить каждый элемент в один результат, а также рекурсивно вызвать unpack_array для элемента. Таким образом, вы обрабатываете вложенные массивы любой глубины:

function unpack_array(arr) {
  if (!Array.isArray(arr)) return [arr];
  
  return arr.reduce((acc, item) => acc.concat(unpack_array(item)), [])
}

console.log(unpack_array([1, [10, 30, 40,[34,53],4],2]))// -> [1,10,30,40,34,53,4,2]

Терминальное условие для рекурсии - если вы достигли элемента, который не является массивом. У вас нет для выполнения return [arr], в этом случае простой return arr также работает, но он просто более последовательный - вы можете вызвать unpack_array(7) и получить массив обратно.

...