JS数组打平方法

  • Post author:
  • Post category:其他


ECMAScript 2019 在 Array.prototype 上增加了两个方法:flat()和 flatMap()。这两个方法为打平数组提供了便利。如果没有这两个方法,则打平数组就要使用迭代或递归。

数组打平也称数组扁平化,就是将数组里面的数组打开,最后合并为一个数组


注意

flat()和 flatMap()只能用于打平嵌套数组。嵌套的可迭代对象如 Map 和 Set不能打平。

在没有这两个方法之前,打平数组就要用迭代或者递归的方法

function flatten(sourceArray,flattenedArray=[]){
            for(const element of sourceArray){
                if(Array.isArray(element)){
                    flatten(element,flattenedArray);
                } else {
                    flattenedArray.push(element);
                }
            }
            return flattenedArray;
        }
        const arr =[[0],1,2,[3,[4,5],6]]
        console.log(flatten(arr)); //[0,1,2,3,4,5,6]

指定打平的级数(通过添加参数depth改写)

function flatten(sourceArray,depth,flattenedArray=[]){
            for(const element of sourceArray){
                if(Array.isArray(element) && depth > 0){
                    flatten(element,depth - 1,flattenedArray);
                } else {
                    flattenedArray.push(element);
                }
            }
            return flattenedArray;
        }
        const arr =[[0],1,2,[3,[4,5],6]]
        console.log(flatten(arr,1)); //[0, 1, 2, 3, Array(2), 6]
        console.log(flatten(arr,2)); //[0, 1, 2, 3, 4, 5, 6]


Array.prototype.flatten()

该方法接收 depth 参数(默认值为 1),返回一个对要打平 Array 实例的浅复制副本。

 		const arr = [[0],1,2,[3,[4,5]],6];
        console.log(arr.flat(2)); //[0, 1, 2, 3, 4, 5, 6]
        console.log(arr.flat()); //[0, 1, 2, 3, [4, 5], 6]

因为是执行浅复制,所以包含循环引用的数组在被打平时会从源数组复制值:

const arr = [[0],1,2,[3,[4,5]],6];
arr.push(arr);
console.log(arr.flat()); //[0, 1, 2, 3, Array(2), 6, Array(1), 1, 2, Array(2), 6, Array(6)]
console.log(arr.flat(2));// [0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, Array(2), 6, Array(1), 1, 2, Array(2),


Array.prototype.flatMap()

Array.prototype.flatMap()方法会在打平数组之前执行一次映射操作。在功能上,arr.flatMap(f)与 arr.map(f).flat()等价;但 arr.flatMap()更高效,因为浏览器只需要执行一次遍历。

flatMap()的函数签名与 map()相同。下面是一个简单的例子:

const arr = [[1],[3],[5]];
console.log(arr.map(([x]) => [x,x+1])); //[[1,2],[3,4],[5,6]]
console.log(arr.flatMap(([x]) => [x,x+1])); //[1, 2, 3, 4, 5, 6]

flatMap()在非数组对象的方法返回数组时特别有用,例如字符串的 split()方法。来看下面的例子,该例子把一组输入字符串分割为单词,然后把这些单词拼接为一个单词数组:

const arr = ['Lorem ipsum dolor sit amet,', 'consectetur adipiscing elit.'];
console.log(arr.flatMap((x) => x.split(/[\W+]/)));
//['Lorem', 'ipsum', 'dolor', 'sit', 'amet', '', 'consectetur', 'adipiscing', 'elit', '']

对于上面的例子,可以利用空数组进一步过滤上一次映射后的结果,去掉了空字符串:

const arr = ['Lorem ipsum dolor sit amet,', 'consectetur adipiscing elit.'];
console.log(arr.flatMap((x) => x.split(/[\W+]/)).flatMap((x) => x || []));
//['Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit']

这里,结果中的每个空字符串首先映射到一个空数组。在打平时,这些空数组就会因为没有内容而被忽略。



版权声明:本文为qq_45954420原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。