[译]JavScript Array.flatMap()

2,747 阅读2分钟

原文链接:JavaScript Array.flatMap()

我们之前已经介绍过 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。厉害👍

资源

(完)