我们之前已经介绍过 Array.flat() 了。现在再讲下 flatMap,这个方法结合了 map() 和 flat() 方法——先映射数组,然后再对映射的结果数组做扁平处理。
const foods = ['🍫', '🍦' ]
// ❌ map + flat
foods.map(food => [food, '😋']).flat()
// ✅ flatMap
foods.flatMap(food => [food, '😋'])
// 结果
// ['🍫', '😋', '🍦', '😋']
flapMap() 的工作原理
接下来我一步步带大家讲述 flapMap() 的运行机制。当我第一次学习的时候,还是有点困惑的。因为我认为它是先 flatten 再 mapping 的。但不是🙅,它是先 map() 再 flat() 的。
const names = ['jane', 'john' ];
// Step 1: map
const nestedArray = names.map((name, index) => [name, index]);
// [ ['jane', 1], ['john', 2 ] ]
OK,现在得到了一个嵌套的数组。然后就可以用 flat() 去扁平化它了。
const nestedArray = [ ['jane', 1], ['john', 2 ] ]
nestedArray.flat();
// [ 'jane', 1, 'john', 2 ]
当然,我们何不简写为 flatMap() 呢。来看下 👀
const names = ['jane', 'john' ];
const result = names.flatMap((name, index) => [name, index]);
// [ 'jane', 1, 'john', 2 ]
瞧!结果是一样的👍
flatMap 仅扁平一层深度
使用 flat() 的时候,我们知道它可以接收一个表示扁平深度的参数 depth。就是说,我们可以把数组扁平化到我们希望的深度。
const depth1 = [ [1], [2] ];
depth1.flat(); // 等同于 depth.flat(1)
// [1, 2]
const depth2 = [ [[1, 2]] ];
depth2.flat(2);
// [1, 2]
而对 flatMap 来说,就不行了,我们只能扁平一层深度。
const names = ['jane'];
names.flatMap((name, index) => [ [name, index] ]);
// [ ['jane', 1] ]
我们把上面代码逻辑拆分成 2 步,看下能看到什么。
const names = ['jane'];
// Step 1: 创建了一个有 2 层深度的数组
const twoLevelDeep = names.map((name, index) => [ [name, index] ]);
// [ [ ['jane', 1] ] ]
// Step 2: 扁平到第一层
twoLevelDeep.flat();
// [ ['jane', 1] ]
当然如果是分开做的话,我们完全可以在第二步指定扁平的深度,通过 depth。
twoLevelDeep.flat(2);
// [ 'jane', 0, 'john', 1 ]
因此,如果你是要扁平超过一层的数组的时候,最好不要选择使用 flatMap() 方法,拆开成 2 步操作吧。
用 flapMap 实现过滤
没想到吧,可以用 flapMap 实现过滤!下面例子里,我们移除了数组中所有的负数。
const numbers = [1, 2, -3, -4, 5];
numbers.flatMap(number => {
return number < 0 ? [] : [number]
})
// [ 1, 2, 5]
cool!这里的表现有点像 filter。但实现的窍门是啥,就是空数组了。
const emptyNestedArray = [ [], 1 ];
emptyNestedArray.flat();
// [ 1 ]
在你尝试扁平一个空数组的时候,这个数组就会被删除。因此,才可以用这个知识点让 flapMap 表现的像 filter。厉害👍
资源
(完)