一个更聪明的JavaScript映射器:array.flatMap()
array.map() 是一个非常有用的映射函数:它接收一个数组和一个映射函数,然后返回一个新的映射的数组。
然而,有一个替代array.map() :array.flatMap() (从ES2019开始可用)。这个方法给了你映射的能力,但也可以在生成的映射数组中删除甚至添加新的项目。
1.更智能的映射器
有一个数字数组,你如何创建一个新的数组,并将其项目加倍?
使用array.map() 函数是一个好方法。
javascript
const numbers = [0, 3, 6];
const doubled = numbers.map(n => n * 2);
console.log(doubled); // logs [0, 6, 12]
numbers.map(number => 2 * number) 将 数组映射到一个新的数组,其中每个数字都被翻倍。numbers
对于你需要映射一个到一个的情况,也就是说,映射的数组将有与原始数组相同的项目数量,array.map() ,效果很好。
但是,如果你需要将一个数组的数字翻倍,同时跳过映射中的零,该怎么办?
直接使用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]
doubled 数组现在包含numbers 的项乘以2,并且不包含任何零。
好的,array.map() 和array.filter() 的组合映射和过滤数组。但是否有更短的方法呢?
有!有!有多亏了array.flatMap() 方法,你只需调用一个方法就可以完成映射和删除项目。
下面是你如何使用array.flatMap() 来返回一个新的映射数组,其中的项是双倍的,同时过滤掉零0 。
javascript
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() 是如何工作的。
2.array.flatMap()
array.flatMap() 函数接受一个回调函数作为参数,并返回一个新的映射的数组。
javascript
const mappedArray = array.flatMap((item, index, origArray) => {
// ...
return [value1, value2, ..., valueN];
}[, thisArg]);
回调函数在原数组中的每个iteam上被调用,有3个参数:当前项、索引和原数组。然后,回调函数返回的数组被平铺1层,得到的项目被添加到映射的数组中。
另外,该方法还接受第二个可选参数,表示回调内部的this 值。
你可以使用array.flatMap() ,最简单的方法是将一个包含项的数组扁平化为数组。
javascript
const arrays = [[2, 4], [6]];
const flatten = arrays.flatMap(item => item);
console.log(flatten); // logs [2, 4, 6]
在上面的例子中,arrays 包含数字的数组:[[2, 4], [6]] 。调用arrays.flatMap(item => item) ,将数组平移到[2, 4, 6] 。
但是array.flatMap() ,除了简单的扁平化,还可以做更多的事情。通过控制你从回调中返回的数组项的数量,你可以。
- 通过返回一个空数组,将该项目从结果数组中删除
[] - 通过返回一个带有一个新值的数组来修改映射的项
[newValue] - 或者通过返回一个有多个值的数组来增加新的项:
[newValue1, newValue2, ...]。
例如,正如你在上一节中所看到的,你可以通过将项翻倍来创建一个新的数组,但也可以删除零0 。
javascript
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() 来增加映射的数组中的项目数量。
例如,下面的代码片段通过增加两倍和三倍的数字将一个数字数组映射成一个新的数组。
javascript
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]
3.总结
array.flatMap() 如果你想把一个数组映射到一个新的数组,同时又能控制你想在新的映射数组中增加多少个项目,那么使用 的回调函数就是一种方法。
array.flatMap(callback) 的回调函数被调用,有3个参数:当前迭代的项、索引和原始数组。然后从回调函数返回的数组在1层深处被平坦化,得到的项被插入到得到的映射数组中。
注意,如果你只想把一个项目映射到一个新的值,那么就争取用标准的array.map() 。
挑战:你能实现一个函数filter(array, predicateFunc) ,使用predicateFunc ,返回一个新的过滤的数组吗?请使用array.flatMap() 来实现。