Flat: примеры (JAVASCRIPT)

Использование функции flat для работы с массивами в JS
Раздел: Массивы, Трансформация
flat(depth?: number): any[]

Основы функции flat

Метод flat() является встроенным методом массивов в JavaScript, предназначенным для рекурсивного выравнивания вложенных массивов. Он создает и возвращает новый массив, в котором все элементы подмассивов конкатенированы в него до указанной глубины.

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

Аргументы

  • depth (необязательный): Число, определяющее глубину выравнивания. По умолчанию равно 1.

Возвращаемое значение

Новый массив с объединенными в него элементами подмассивов до указанной глубины. Исходный массив не изменяется.

Простые примеры использования

Выравнивание на одну глубину (по умолчанию)

const arr1 = [1, 2, [3, 4]];
console.log(arr1.flat());
// Результат: [1, 2, 3, 4]

Выравнивание с указанием глубины

const arr2 = [1, 2, [3, 4, [5, 6]]];
console.log(arr2.flat());
console.log(arr2.flat(2));
// Результат flat(): [1, 2, 3, 4, [5, 6]]
// Результат flat(2): [1, 2, 3, 4, 5, 6]

Использование Infinity

const arr3 = [1, [2, [3, [4, [5]]]]];
console.log(arr3.flat(Infinity));
// Результат: [1, 2, 3, 4, 5]

Работа с пустыми слотами

const arr4 = [1, 2, , 4, [5, , 7]];
console.log(arr4.flat());
// Результат: [1, 2, 4, 5, 7]
// Пустые слоты удаляются.

Похожие методы в JavaScript

Array.prototype.flatMap()

Комбинирует операции map() и flat() с глубиной 1. Сначала применяет функцию к каждому элементу, затем выравнивает результат. Эффективен для случаев, где после преобразования требуется немедленное выравнивание.

const arr = [1, 2, 3];
console.log(arr.flatMap(x => [x, x * 2]));
// Результат: [1, 2, 2, 4, 3, 6]

Ручная рекурсия или reduce с concat

До появления flat() использовались самописные рекурсивные функции или комбинация reduce и concat. flat() предпочтительнее из-за читаемости и производительности.

Частые ошибки

Передача нечислового аргумента depth

const arr = [1, [2]];
console.log(arr.flat('hello')); // Аргумент преобразуется в число
console.log(arr.flat(null)); // null становится 0
console.log(arr.flat({})); // NaN трактуется как 0
// Результат для 'hello': [1, [2]] (NaN -> 0)
// Результат для null: [1, [2]] (0)
// Результат для {}: [1, [2]] (NaN -> 0)

Ожидание изменения исходного массива

const original = [1, [2]];
const flattened = original.flat();
console.log(original); // Исходный массив не изменился
// Результат: [1, [2]]

Попытка выровнять не-массив

const notArray = { 0: [1, 2], length: 1 };
// notArray.flat(); // TypeError: notArray.flat is not a function
// Работает только для настоящих массивов.

История изменений

Метод flat() был стандартизирован в спецификации ECMAScript 2019 (ES10). До этого он был доступен в некоторых браузерах как экспериментальная функция. В более ранних версиях JavaScript требуется использование полифилов или альтернативных подходов.

Расширенные примеры

Обработка данных из API

Пример javascript
// Предположим, API возвращает список постов, где каждый пост имеет список тегов.
const apiResponse = [
    { id: 1, tags: ['js', 'web'] },
    { id: 2, tags: ['node', 'backend'] },
    { id: 3, tags: ['js', 'frontend'] }
];
// Получить все уникальные теги.
const allTags = apiResponse
    .map(post => post.tags) // [['js','web'], ['node','backend'], ...]
    .flat(); // ['js', 'web', 'node', 'backend', 'js', 'frontend']
const uniqueTags = [...new Set(allTags)];
console.log(uniqueTags);
// Результат: ['js', 'web', 'node', 'backend', 'frontend']

Сглаживание результатов нескольких map

Пример javascript
const matrix = [[1, 2], [3, 4], [5, 6]];
// Задача: умножить каждый элемент на 2 и получить одномерный массив.
const result = matrix
    .map(row => row.map(x => x * 2)) // [[2,4], [6,8], [10,12]]
    .flat(); // или flatMap(row => row.map(x => x * 2))
console.log(result);
// Результат: [2, 4, 6, 8, 10, 12]

Удаление пустых элементов при выравнивании

Пример javascript
const data = [1, null, [2, undefined, 3], , [4, [ , 5]]];
const flattened = data.flat(Infinity).filter(el => el != null);
console.log(flattened);
// Результат: [1, 2, 3, 4, 5]
// Удалены null, undefined и пустые слоты.

Имитация flat с помощью reduce и concat

Пример javascript
function flatten(arr, depth = 1) {
    return depth > 0
        ? arr.reduce((acc, val) =>
            acc.concat(Array.isArray(val) ? flatten(val, depth - 1) : val), [])
        : arr.slice();
}
console.log(flatten([1, [2, [3]]], 1));
// Результат: [1, 2, [3]]

Аналоги функции в других языках

Python (itertools.chain, списковые включения)

from itertools import chain
nested_list = [[1, 2], [3, 4]]
flattened = list(chain.from_iterable(nested_list))
print(flattened)
# Или
flattened = [item for sublist in nested_list for item in sublist]
# Результат: [1, 2, 3, 4]

PHP (array_merge в цикле, итератор RecursiveArrayIterator)

$array = [[1, 2], [3, 4]];
$flattened = array_merge(...$array); // Только один уровень
print_r($flattened);
// Для рекурсии
$array = [1, [2, [3]]];
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$flattened = iterator_to_array($iterator, false);
/* Результат первого:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
Результат второго:
Array ( [0] => 1 [1] => 2 [2] => 3 ) */

C# (LINQ SelectMany)

using System.Linq;
var nested = new int[][] { new int[] {1, 2}, new int[] {3, 4} };
var flattened = nested.SelectMany(x => x).ToArray();
// Результат: [1, 2, 3, 4]

MySQL (JSON_TABLE, рекурсивные CTE)

Для работы с табличными данными выравнивание достигается через соединения или рекурсивные запросы, что концептуально отличается от работы с массивами.

JS flat function comments

En
Flat Creates a new array with all sub-array elements concatenated into it recursively up to the specified depth