JS `Array.prototype.flat()` / `flatMap()` (ES2019):扁平化嵌套数组

各位程序猿/媛们,晚上好! 今天咱们来聊聊JavaScript里两个有点意思的家伙:Array.prototype.flat()Array.prototype.flatMap()。 它们就像数组界的“铲平大师”,专门用来对付那些嵌套得像俄罗斯套娃一样的数组。 准备好了吗? 咱们开始咯!

一、 什么是扁平化? 为什么要扁平化?

首先,得弄明白啥是“扁平化”。 简单来说,扁平化就是把一个多维数组(就像一个里面套着好几个盒子的盒子)变成一个一维数组(就像把所有盒子里的东西都倒出来,摊平了)。

那么,为什么要扁平化呢? 想象一下,你从一个接口拿到了一个数据,它的结构是这样的:

const nestedArray = [
  1,
  [2, 3],
  [4, [5, 6]],
  7
];

如果你想遍历这个数组,把所有的数字都加起来,你会怎么做? 你得先判断每个元素是不是数组,如果是,就得递归进去,再判断… 哎呀,想想就头大!

但是,如果把这个数组扁平化成这样:

const flatArray = [1, 2, 3, 4, 5, 6, 7];

遍历起来是不是就简单多了? 直接一个 for 循环或者 forEach 就搞定了。

所以,扁平化的目的就是简化数据结构,方便后续处理。

二、 Array.prototype.flat(): 一铲平到底!

flat() 方法会创建一个新数组,其中所有子数组元素都以递归方式连接到该数组中,直到达到指定的深度。 它的语法是这样的:

array.flat([depth])
  • depth (可选): 指定要提取嵌套数组结构的深度。 默认值为 1。 可以是 Infinity,表示无限深度,也就是不管嵌套多深,都给你铲平了。

咱们来看几个例子:

例1: 默认深度(1)

const nestedArray = [1, [2, 3], [4, [5, 6]]];
const flatArray = nestedArray.flat();
console.log(flatArray); // 输出: [1, 2, 3, 4, [5, 6]]

可以看到,只铲平了一层, [5, 6] 还是个数组。

例2: 指定深度(2)

const nestedArray = [1, [2, 3], [4, [5, 6]]];
const flatArray = nestedArray.flat(2);
console.log(flatArray); // 输出: [1, 2, 3, 4, 5, 6]

这下好了,两层都被铲平了, [5, 6] 也被提取出来了。

例3: 无限深度 (Infinity)

const nestedArray = [1, [2, [3, [4, [5]]]]];
const flatArray = nestedArray.flat(Infinity);
console.log(flatArray); // 输出: [1, 2, 3, 4, 5]

不管嵌套多深, Infinity 都能搞定,一铲平到底!

例4: 数组中有空位 (empty)

flat() 方法会移除数组中的空位。

const nestedArray = [1, , [2, 3], , [4, [5, 6]]]; //注意这里有两个空位
const flatArray = nestedArray.flat();
console.log(flatArray); // 输出: [1, 2, 3, 4, [5, 6]]

可以看到,空位被移除了。 这在处理一些特殊数据的时候可能会有用。

三、 Array.prototype.flatMap(): 映射 + 扁平化,一步到位!

flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。 它相当于先 map()flat(),但效率更高。 它的语法是这样的:

array.flatMap(function(currentValue[, index[, array]]) {
  // 返回新数组的元素
}[, thisArg])
  • callback: 为数组中的每个元素执行的函数,返回新数组的元素。
  • currentValue: 数组中正在处理的当前元素。
  • index (可选): 数组中正在处理的当前元素的索引。
  • array (可选): 被调用的数组。
  • thisArg (可选): 执行 callback 时用作 this 的值。

flatMap() 的深度固定为 1。 也就是说,它只会扁平化一层。

咱们来看几个例子:

例1: 简单的映射和扁平化

const array = [1, 2, 3];
const flatMappedArray = array.flatMap(x => [x * 2]);
console.log(flatMappedArray); // 输出: [2, 4, 6]

这个例子中,map() 函数将每个元素乘以 2, 然后 flatMap() 将结果扁平化成一个一维数组。

例2: 生成多个元素

const array = [1, 2, 3];
const flatMappedArray = array.flatMap(x => [x, x * 2]);
console.log(flatMappedArray); // 输出: [1, 2, 2, 4, 3, 6]

这个例子中,map() 函数为每个元素生成两个元素: 原来的元素和它的两倍。 flatMap() 将这些元素扁平化到一个数组中。

例3: 过滤元素

flatMap() 也可以用来过滤元素。 如果 map() 函数返回一个空数组 [],那么这个元素就会被过滤掉。

const array = [1, 2, 3, 4, 5];
const flatMappedArray = array.flatMap(x => x % 2 === 0 ? [x] : []);
console.log(flatMappedArray); // 输出: [2, 4]

这个例子中,只有偶数才会被保留下来。

例4: 处理字符串数组

const sentences = ["This is a sentence.", "This is another sentence."];
const words = sentences.flatMap(sentence => sentence.split(" "));
console.log(words);
// 输出: ["This", "is", "a", "sentence.", "This", "is", "another", "sentence."]

这个例子展示了如何使用 flatMap() 将一个字符串数组转换成一个单词数组。

四、 flat() vs flatMap(): 选哪个?

| 特性 | flat() | flatMap() |
| 适用场景 | 只需要扁平化数组,不需要进行映射操作。 | 需要先对数组元素进行映射操作,然后再进行扁平化操作。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注