Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。

Array.prototype.flatMap()

BaselineWidely available

flatMap() 方法对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组。它等价于在调用map() 方法后再调用深度为 1 的flat() 方法(arr.map(...args).flat()),但比分别调用这两个方法稍微更高效一些。

尝试一下

const arr1 = [1, 2, 1];const result = arr1.flatMap((num) => (num === 2 ? [2, 2] : 1));console.log(result);// Expected output: Array [1, 2, 2, 1]

语法

js
flatMap(callbackFn)flatMap(callbackFn, thisArg)

参数

callbackFn

一个在数组的每个元素上执行的函数。它应该返回一个包含新数组元素的数组,或是要添加到新数组中的单个非数组值。该函数将被传入以下参数:

element

数组中正在处理的当前元素。

index

数组中正在处理的当前元素的索引。

array

调用flatMap() 的当前数组。

thisArg可选

在执行callbackFn 时用作this 的值。参见迭代方法

返回值

一个新的数组,其中每个元素都是回调函数的结果,并且被展开一级。

描述

flatMap() 方法是一个迭代方法。有关回调函数的详细说明,请参见Array.prototype.map()flatMap() 方法等同于调用map(callbackFn, thisArg) 后再调用flat(1)——对于每个元素,它都会生成一个新元素数组,并将生成的数组连接起来形成一个新数组。

flatMap() 方法是通用的。它只需要this 值具有length 属性和整数键属性即可。但是,如果要展开从回调函数callbackFn 返回的值,则该值必须是数组。

替代方案

预分配数组并显式迭代

js
const arr = [1, 2, 3, 4];arr.flatMap((x) => [x, x * 2]);// 等价于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() 与 flatMap()

js
const arr1 = [1, 2, 3, 4];arr1.map((x) => [x * 2]);// [[2], [4], [6], [8]]arr1.flatMap((x) => [x * 2]);// [2, 4, 6, 8]// 只有一层被展平arr1.flatMap((x) => [[x * 2]]);// [[2], [4], [6], [8]]

虽然上面的示例可以通过使用map() 方法自行实现,但下面的示例更好地展示了flatMap() 方法的用法。

让我们从一组句子中生成单词列表。

js
const arr1 = ["it's Sunny in", "", "California"];arr1.map((x) => x.split(" "));// [["it's","Sunny","in"],[""],["California"]]arr1.flatMap((x) => x.split(" "));// ["it's","Sunny","in", "", "California"]

请注意,输出列表长度可能与输入列表长度不同。

map() 方法过程中添加和删除元素

flatMap 方法可以用作在map 方法中添加和删除元素(修改元素数量)的方法。换句话说,它允许你将一些项处理为另一些项(通过单独处理每个输入项),而不总是一对一的。在这个意义上,它的作用类似于filter 的相反操作。如果要保留该项,则返回一个包含该项的单元素数组,如果要添加元素,则返回一个包含多个元素的数组,如果要删除该项,则返回一个空数组。

js
// 假设我们想要删除所有负数,并将奇数拆分成偶数和 1const 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]

在稀疏数组上使用 flatMap()

callbackFn 不会被源数组中的空槽调用,因为map() 不会调用,而flat() 将忽略返回数组中的空槽。

js
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() 方法读取thislength 属性,然后访问每个整数索引。如果回调函数的返回值不是数组,则始终直接将其附加到结果数组的末尾。

js
const arrayLike = {  length: 3,  0: 1,  1: 2,  2: 3,};console.log(Array.prototype.flatMap.call(arrayLike, (x) => [x, x * 2]));// [1, 2, 2, 4, 3, 6]// 回调函数返回的类数组对象不会被展平console.log(  Array.prototype.flatMap.call(arrayLike, (x) => ({    length: 1,    0: x,  })),);// [ { '0': 1, length: 1 }, { '0': 2, length: 1 }, { '0': 3, length: 1 } ]

规范

Specification
ECMAScript® 2026 Language Specification
# sec-array.prototype.flatmap

浏览器兼容性

参见

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp