Flat: примеры (JAVASCRIPT)
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
// Предположим, 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
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]
Удаление пустых элементов при выравнивании
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
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)
Для работы с табличными данными выравнивание достигается через соединения или рекурсивные запросы, что концептуально отличается от работы с массивами.