array.map()
是一个非常有用的映射函数:它接收一个数组和一个映射函数,然后返回一个新的映射数组。
然而,有一个替代 array.map()
的方法:array.flatMap()
(从 ES2019 开始可用)。这个方法给了我们映射的能力,但也可以在生成的映射数组中删除甚至添加新的项目。
更加智能的映射器
有一个数字数组,我们要如何创建一个新的数组,使用每个数字加倍?
使用array.map()
函数是一个好方法。
const numbers = [0, 3, 6]; const doubled = numbers.map(n => n * 2); console.log(doubled); // logs [0, 6, 12]
numbers.map(number => 2 * number)
将 number
数组映射到一个新的数组,其中每个数字都被翻倍。
对于需要一对一映射的情况,也就是说,映射后的数组与原始数组的项数相同,array.map()
的效果非常好。
但如果我们需要将一个数组的数字翻倍,同时跳为0
的项,该怎么办?
直接使用 array.map()
是不可能的,因为该方法总是创建一个映射的数组,其项数与原数组相同。但是我们可以使用 array.map()
和 array.filter()
的组合。
const numbers = [0, 3, 6]; const doubled = numbers .filter(n => n !== 0) .map(n => n * 2); console.log(doubled); // logs [6, 12]
array.map()
和 array.filter()
可以解决问题,但有没有更简短的方法?
必须滴。使用 array.flatMap()
方法,只需调用一个方法就可以执行映射和删除项目。
const numbers = [0, 3, 6]; const doubled = numbers.flatMap(number => { return number === 0 ? [] : [2 * number]; }); console.log(doubled); // logs [6, 12]
通过只使用 numbers.flatMap()
,你可以将一个数组映射到另一个数组,但也可以从映射中跳过某些元素。
接着,我们来更详细地看看 array.flatMap()
是如何工作的。
array.flatMap()
array.flatMap()
函数接受一个回调函数作为参数并返回一个新的映射数组。
const mappedArray = array.flatMap((item, index, origArray) => { // ... return [value1, value2, ..., valueN]; }[, thisArg]);
回调函数在原数组中的每个 iteam 上被调用,有 3 个参数:当前项、索引和原数组。然后,回调函数返回的数组被扁平化了 1 层,得到的项目被添加到映射的数组中。
此外,该方法还接受第二个可选参数,表示回调内部的 this
值。
使用 array.flatmap()
最简单的方法是将包含项目的数组扁平化。
const arrays = [[2, 4], [6]]; const flatten = arrays.flatMap(item => item); console.log(flatten); // logs [2, 4, 6]
但是array.flatMap()
除了简单的扁平化之外,还可以做更多的事情。通过控制从回调中返回的数组项的数量:
- 通过返回一个空数组从结果数组中删除该项
- 通过返回一个带有一个新值的数组
[newValue]
来修改映射的项 - 通过返回一个包含多个值的数组来添加新项:
[newValue1, newValue2, ...]
例如,正如你在上一节中所看到的,可以通过将项目加倍来创建一个新的数组,但同时也要删除 0
。
const numbers = [0, 3, 6]; const doubled = numbers.flatMap(number => { return number === 0 ? [] : [2 * number]; }); console.log(doubled); // logs [6, 12]
现在,我们来看下它是怎么工作的。
如果当前项为 0
,回调函数返回一个空数组 []
。这意味着当被扁平化时,空数组[]
没有提供任何值。
如果当前迭代项非零,则返回 [2 * number]
。当扁平[2 * number]
数组时,结果数组中只添加2 * number
。
你也可以使用 array.flatMap()
来增加映射的数组中的项目数量。
例如,下面的代码片段通过添加两倍和三倍的数字将一个数字数组映射到一个新数组:
const numbers = [1, 4]; const trippled = numbers.flatMap(number => { return [number, 2 * number, 3 * number]; }); console.log(trippled); // logs [1, 2, 3, 4, 8, 12]
总结
如果你想把一个数组映射到一个新的数组中,同时又能控制你想在新的映射数组中添加多少项,那么 array.flatMap()
方法就是一个好办法。
array.flatMap(callback)
的回调函数被调用,有 3 个参数:当前迭代的项、索引和原始数组。然后,从回调函数返回的数组在1
层深处被扁平化,得到的项目被插入到所产生的映射数组中。