Skip to main content

Плаский масив з багатовимірного

«Розплющити» масив означає перетворити вкладену структуру на один плаский список значень. У сучасному JavaScript для цього є метод flat(), який приймає глибину розгортання; решта способів (рекурсія, flatMap(), toString()) залишаються корисними в окремих випадках.

Теорія

TL;DR

  • arr.flat() розгортає один рівень вкладеності.
  • arr.flat(2) розгортає два рівні, arr.flat(Infinity) розгортає все.
  • Жоден із цих способів не змінює вихідний масив, усі повертають новий.
  • До ES2019 писали рекурсивний flatten на reduce() плюс Array.isArray().
  • flatMap() це map() плюс розгортання одного рівня за один прохід.
  • toString().split(',') працює лише для чисел і рядків і повертає рядки.

Швидкий приклад

Маємо масив:

javascript
const arr = [1, [2, 3], [4, [5, 6]]];

Хочемо отримати [1, 2, 3, 4, 5, 6]:

javascript
console.log(arr.flat(Infinity)); // [1, 2, 3, 4, 5, 6]

flat() і глибина розгортання

Найпростіший спосіб це flat() (ES2019 і новіші):

javascript
const flattened = arr.flat(); console.log(flattened); // [1, 2, 3, 4, [5, 6]]

За замовчуванням flat() розгортає лише один рівень вкладеності. Глибину можна задати аргументом:

javascript
const deeplyFlattened = arr.flat(2); console.log(deeplyFlattened); // [1, 2, 3, 4, 5, 6]
  • flat(1) це один рівень,
  • flat(2) це два рівні,
  • flat(Infinity) це повне розгортання, незалежно від глибини.

Приклад із глибокою вкладеністю:

javascript
const nested = [1, [2, [3, [4]]]]; console.log(nested.flat(Infinity)); // [1, 2, 3, 4]

Це найзручніший і найсучасніший спосіб зробити масив пласким. Бонусом flat() прибирає порожні комірки розрідженого масиву: [1, , 3].flat() дає [1, 3].

Рекурсія, спосіб до flat()

javascript
function flatten(arr) { return arr.reduce( (acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val), [] ); } console.log(flatten([1, [2, [3, 4]], 5])); // [1, 2, 3, 4, 5]
  • перевіряємо кожен елемент: якщо це масив, викликаємо flatten рекурсивно;
  • якщо ні, додаємо значення до результату.

Цей варіант досі корисний, коли потрібна власна логіка, наприклад пропускати null або розгортати лише певні гілки.

toString() для чисел і рядків

javascript
[1, [2, [3, 4]]].toString().split(','); // ["1", "2", "3", "4"]

Працює, тільки якщо в масиві немає об'єктів чи null, бо все перетворюється на рядки. Числа після такого перетворення теж стають рядками, тож це радше трюк, ніж робочий підхід.

flatMap() для перетворення разом із розгортанням

javascript
const arr = [1, 2, [3, 4]]; const result = arr.flatMap(x => (Array.isArray(x) ? x : [x])); console.log(result); // [1, 2, 3, 4]

flatMap() одночасно перетворює елементи і розгортає один рівень, тому він економить зайвий прохід порівняно з map().flat().

Порівняння способів

СпосібПрацює зГлибинаМутуєСучасність
arr.flat()масив1 за замовчуваннямНіТак, ES2019 і новіші
arr.flat(Infinity)багатовимірнийусі рівніНіТак
Рекурсіямасивбудь-якаНіТак, універсально
flatMap()масив1 рівеньНіТак
toString().split()числа, рядкиусі рівніНіОбмежено

Підсумок: щоб зробити масив пласким,

javascript
const flat = arr.flat(Infinity);

це коротко, безпечно і зрозуміло.

Типові помилки

  • Очікувати, що flat() розгорне все. Без аргументу він знімає рівно один рівень; для глибокої структури потрібен flat(Infinity).
  • Вважати, що flat() змінює масив. Він повертає новий масив, тому результат треба присвоїти: arr = arr.flat().
  • toString().split(',') на об'єктах. Об'єкти перетворяться на [object Object], а null і undefined стануть порожніми рядками.
  • Втрата типів після split(). Числа повертаються рядками, тож потрібне додаткове .map(Number).
  • Рекурсія без базового випадку по типу. Якщо не перевіряти Array.isArray(val), рядок теж піде в рекурсію, бо його можна ітерувати.
  • flatMap() замість глибокого розгортання. Він знімає тільки один рівень, тому для [[1, [2]]] результат залишиться вкладеним.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.