数组扁平化的几种方式你熟悉嘛

95 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情

数组扁平化在我们日常生活中还是十分常见的,比如后台返回我们的数组中还包含二维数组,而我们又需要它是一维数组,这时候就需要将这个多维数组展开了。

数组扁平化的方法很多,下面我们就来一起看看它有哪些方法吧!

flat

ES6的数组新增了一个API,专门用于数组的扁平化,这也是我日常中使用最多的方法。它有一个可选参数,这个参数的作用是将数组扁平化几层,如果不传参就默认为1。

let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.flat())  // [1, 2, 3, 4, 5, 6, [7, 8], 9, 0]

我们发现它只是展开了一层,如果要全展开就需要传递参数2:

let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.flat(2))  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

但是有时候我们不知道层数怎么办?那就可以传递Infinity作为参数,它的作用就是将它扁平化为1维数组:

let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.flat(Infinity))  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

toString与split

数组重写了toString方法,它的toString不再是返回类型,而是返回数组的所有数值的字符串,并以逗号分隔。

let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.toString())  // 1,2,3,4,5,6,7,8,9,0

然后我们再使用split将字符串转为数组就可以了。

let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.toString().split(','))  //  ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']

不过它有一个缺点,就是会改变这个数值的类型,将它转为了string类型了。如果数组中包含对象类型或者函数的话,这个方法就得pass,因为它会将对象转为[object Object],将函数转为字符串.

let aa = function(){}
let a = [1,2,[3,true],{a:1},[6,[7,aa],9],0];
console.log(a.toString().split(','))

image.png

递归

我们也可以使用老办法———递归的方式进行数组的扁平化:

原理就是使用concat的方式进行拼接。

function myFlatten(arrays) {
    let arr = [];
    arrays.forEach((item, index) => {
        if (Array.isArray(item)) {
            arr = arr.concat(myFlatten(item));
        } else {
            arr.push(item)
        }
    })
    return arr;
}
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(myFlatten(a));  //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

我们发现这会开辟很多空间,会声明很多的arr。

reduce改进

function myFlatten(arrays) {
    return arrays.reduce((arr,now)=>{
        if(Array.isArray(now)) {
            arr = arr.concat(myFlatten(now))
        } else {
            arr.push(now)
        }
        return arr
    },[])
}
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(myFlatten(a));  //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

扩展运算符

我们也可以使用ES6新增的扩展运算符来进行数组的扁平化。扩展运算符的作用就是将可迭代对象展开。

let a = [1,2,3,[4,[5,6,[7]]]];
console.log(...a);  // 1,2,3,[4,[5,6,[7]]]let str = 'aaaaa';
console.log(...str)  // a a a a alet set = new Set([1,2,3])
console.log(...set)  // 1 2 3
...

所以它是不是有一点像flat(1)呢?

function myFlatten(arrays) {
    while(arrays.some((item)=>Array.isArray(item))) {  
        arrays = [].concat(...arrays);  // 循环了两次
    }
    return arrays;
}
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(myFlatten(a));  //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

正则

最后一种使用方式就是正则了,先使用JSON.stringify()对其进行序列化,然后使用正则去掉所有的 '[' 和 ']' ,最后再在外面包裹一层就可以了。

function myFlatten6(arrays) {
    let str = JSON.stringify(arrays);
    str = str.replace(/([|])/g,'')
    str = `[${str}]`;
    return str;
}
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(myFlatten6(a)); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]