Array.prototype.flatMap()
Базовый уровень Широко доступен
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и в различных версиях браузеров. Она доступна во всех браузерах с января 2020 года.
Метод flatMap() экземпляров Array возвращает новый массив, сформированный путем применения заданной функции обратного вызова к каждому элементу массива, а затем сглаживания результата на один уровень. Он идентичен вызову map() с последующим вызовом flat() с глубиной 1 (arr.map(...args).flat()), но немного более эффективен, чем вызов этих двух методов по отдельности.
Попробуйте
const arr = [1, 2, 1]; const result = arr.flatMap((num) => (num === 2 ? [2, 2] : 1)); console.log(result); // Expected output: Array [1, 2, 2, 1]
Синтаксис
flatMap(callbackFn) flatMap(callbackFn, thisArg)
Параметры
-
callbackFn - Функция, которая будет выполняться для каждого элемента в массиве. Она должна возвращать массив, содержащий новые элементы для нового массива, или одно значение, не являющееся массивом, которое будет добавлено в новый массив. Функция вызывается со следующими аргументами:
-
element - Текущий обрабатываемый элемент в массиве.
-
index - Индекс текущего обрабатываемого элемента в массиве.
-
array - Массив, к которому был применён
flatMap().
-
-
thisArgНеобязательно - Значение, используемое в качестве
thisпри выполненииcallbackFn. См. итеративные методы.
Возвращаемое значение
Новый массив, каждый элемент которого является результатом функции обратного вызова и который сглажен на глубину 1.
Описание
Метод flatMap() является итеративным методом. См. Array.prototype.map() для подробного описания функции обратного вызова. Метод flatMap() идентичен вызову map(callbackFn, thisArg) с последующим вызовом flat(1) — для каждого элемента он создает массив новых элементов и объединяет (конкатенирует) полученные массивы для формирования нового массива. Прочтите раздел итеративные методы для получения дополнительной информации о том, как эти методы работают в целом.
Метод flatMap() является обобщенным. Он ожидает, что значение this будет иметь свойство length и свойства с целочисленными ключами. Однако, значение, возвращаемое из callbackFn, должно быть массивом, если его нужно сглаживать.
Альтернатива
Предварительное выделение памяти и явная итерация
const arr = [1, 2, 3, 4];
arr.flatMap((x) => [x, x * 2]);
// is equivalent to
const n = arr.length;
const acc = new Array(n * 2);
for (let i = 0; i < n; i++) {
const x = arr[i];
acc[i * 2] = x;
acc[i * 2 + 1] = x * 2;
}
// [1, 2, 2, 4, 3, 6, 4, 8]
Обратите внимание, что в данном конкретном случае подход flatMap медленнее, чем подход с циклом for — из-за создания временных массивов, которые должны быть очищены сборщиком мусора, а также из-за того, что размер возвращаемого массива не нужно часто изменять. Однако, flatMap все равно может быть правильным решением в тех случаях, когда важна его гибкость и читаемость.
Примеры
map() and flatMap()
const arr = [1, 2, 3, 4]; arr.map((x) => [x * 2]); // [[2], [4], [6], [8]] arr.flatMap((x) => [x * 2]); // [2, 4, 6, 8] // only one level is flattened arr.flatMap((x) => [[x * 2]]); // [[2], [4], [6], [8]]
Хотя вышеуказанное могло быть достигнуто с помощью map, вот пример, который лучше демонстрирует использование flatMap().
Давайте сгенерируем список слов из списка предложений.
const arr = ["it's Sunny in", "", "California"];
arr.map((x) => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]
arr.flatMap((x) => x.split(" "));
// ["it's","Sunny","in", "", "California"]
Обратите внимание, длина выходного списка может отличаться от длины входного списка.
Для добавления и удаления элементов во время map()
flatMap можно использовать как способ добавления и удаления элементов (изменения количества элементов) во время map. Другими словами, он позволяет отображать много элементов во много элементов (путем отдельной обработки каждого входного элемента), а не всегда один к одному. В этом смысле он работает как противоположность filter. Верните массив из 1 элемента, чтобы сохранить элемент, массив из нескольких элементов, чтобы добавить элементы, или массив из 0 элементов, чтобы удалить элемент.
// Let's say we want to remove all the negative numbers
// and split the odd numbers into an even number and a 1
const a = [5, 4, -3, 20, 17, -33, -4, 18];
// |\ \ x | | \ x x |
// [4,1, 4, 20, 16, 1, 18]
const result = a.flatMap((n) => {
if (n < 0) {
return [];
}
return n % 2 === 0 ? [n] : [n - 1, 1];
});
console.log(result); // [4, 1, 4, 20, 16, 1, 18]
Использование третьего аргумента callbackFn
Аргумент array полезен, если вы хотите получить доступ к другому элементу в массиве, особенно если у вас нет существующей переменной, ссылающейся на массив. Следующий пример сначала использует filter() для извлечения работающих станций, а затем использует flatMap() для создания нового массива, где каждый элемент содержит станцию и ее следующую станцию. На последней станции он возвращает пустой массив, чтобы исключить ее из конечного массива.
const stations = ["New Haven", "West Haven", "Milford (closed)", "Stratford"];
const line = stations
.filter((name) => !name.endsWith("(closed)"))
.flatMap((name, idx, arr) => {
// Without the arr argument, there's no way to easily access the
// intermediate array without saving it to a variable.
if (idx === arr.length - 1) return []; // last station has no next station
return [`${name} - ${arr[idx + 1]}`];
});
console.log(line); // ['New Haven - West Haven', 'West Haven - Stratford']
Аргумент array не является массивом, который строится — нет способа получить доступ к строящемуся массиву из функции обратного вызова.
Использование flatMap() на разреженных массивах
callbackFn не будет вызываться для пустых слотов в исходном массиве, поскольку map() этого не делает, в то время как flat() игнорирует пустые слоты в возвращаемых массивах.
console.log([1, 2, , 4, 5].flatMap((x) => [x, x * 2])); // [1, 2, 2, 4, 4, 8, 5, 10] console.log([1, 2, 3, 4].flatMap((x) => [, x * 2])); // [2, 4, 6, 8]
Вызов flatMap() для объектов, не являющихся массивами
Метод flatMap() считывает свойство length объекта this, а затем обращается к каждому свойству, ключ которого является неотрицательным целым числом, меньшим, чем length. Если возвращаемое значение функции обратного вызова не является массивом, оно всегда напрямую добавляется в результирующий массив.
const arrayLike = {
length: 3,
0: 1,
1: 2,
2: 3,
3: 4, // ignored by flatMap() since length is 3
};
console.log(Array.prototype.flatMap.call(arrayLike, (x) => [x, x * 2]));
// [1, 2, 2, 4, 3, 6]
// Array-like objects returned from the callback won't be flattened
console.log(
Array.prototype.flatMap.call(arrayLike, (x) => ({
length: 1,
0: x,
})),
);
// [ { '0': 1, length: 1 }, { '0': 2, length: 1 }, { '0': 3, length: 1 } ]
Спецификации
Совместимость с браузерами
| Рабочий стол | Мобильные устройства | Сервер | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on iOS | Samsung Internet | WebView Android | WebView on iOS | Bun | Deno | Node.js | |
flatMap |
69 |
79 |
62 |
56 |
12 |
69 |
62 |
48 |
12 |
10.0 |
69 |
12 |
1.0.0 |
1.0 |
11.0.0 |
См. также
- Полифилл
Array.prototype.flatMapвcore-js - Полифилл
Array.prototype.flatMapот es-shims - Руководство по Indexed collections
ArrayArray.prototype.concat()Array.prototype.flat()Array.prototype.map()Array.prototype.reduce()
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap