数组扁平化

759 阅读3分钟

什么是数组扁平化

什么是数组扁平化?数组扁平化就将一个多层嵌套的数组变成一个单层数组,如:[1, [2, [3, [4, [5]]]]]---->[1,2,3,4,5]
数组扁平化作为前端面试的一个经典面试题,今天我就和大家来聊聊实现数组扁平化的N种方式。

实现的7种方式

1. arr.flat(Infinity)

flat作为ES6的新特性,只要调用该方法便可以简单快速实现数组的扁平化,使用起来确实很容易上手(可以说是0门槛),但是只会这个方法是没有办法得到面试官的青睐的!

const arr = [1, [2, [3, [4, [5]]]]];

// 1. flat自动展开
let arr1 = arr.flat(Infinity);
console.log(arr1); // [ 1, 2, 3, 4, 5 ]

2. replace + split

思想:将数组先转变为字符串,再使用正则去除所有的中括号,最后将剩下的字符串以逗号为分隔符生成字符串。

但是这种方法存在一个缺点,生成出来的数组每一项都是字符串,而非原来的数字

const arr = [1, [2, [3, [4, [5]]]]];

// 将arr变成字符串
let str = JSON.stringify(arr);
console.log(str); // [1,[2,[3,[4,[5]]]]] String

// 2. replace + split
// 使用正则去除str里面的[]两个符号
let arr2 = str.replace(/(\[|\])/g, '');
console.log(arr2); // 1,2,3,4,5
// 以,为间隔生成数组
arr2 = arr2.split(',');
console.log(arr2); //[ '1', '2', '3', '4', '5' ]

// 整合成一行代码如下
let arr3 = str.replace(/(\[|\])/g, '').split(',');
console.log(arr3);// [ '1', '2', '3', '4', '5' ]

3. replace + JSON.parse

思想:同样先转化成字符串,去除所有的中括号,但最后在两个使用中括号包围起来,再调用JSON.parse方法自动转化为数组

此方法对上一个方法进行了一点改进,解决了生成的数组都是字符的问题

const arr = [1, [2, [3, [4, [5]]]]];

// 将arr变成字符串
let str = JSON.stringify(arr);
console.log(str); // [1,[2,[3,[4,[5]]]]] String

// 3. replace + JSON.parse
// 先去除所有的括号
let str2 = str.replace(/(\[|\])/g, '');
// 再加上左右括号
str2 = '[' + str2 + ']';
str2 = JSON.parse(str2); // 真正意义上实现的数组扁平化
console.log(str2);  // [ 1, 2, 3, 4, 5 ]  Array

4. map思想

map思想是将数组中所有字符取出来,再次生成数组同时将所有字符转变为数字类型,也算是对上面第二个方法的一种优化。

const arr = [1, [2, [3, [4, [5]]]]];

function flatten(arr) {
    return arr.toString().split(',').map(function (item) {
        return +item //+可以快速获得Number类型
    })
}

console.log(flatten(arr));  // [ 1, 2, 3, 4, 5 ]

5. 扩展运算符(...)

此方法借用了数组中的Array.isArray和some方法,使用while循环来不断对数组判断里面是否有数组,存在就使用...将其展开,也算是一种比较便捷的方法。

const arr = [1, [2, [3, [4, [5]]]]];
function Flatten(array) {
    // 使用Array.isArray判断数组中是否有数组嵌套
    // 使用some方法进行控制while循环
    while (array.some((item) => Array.isArray(item))) {
        // 将数组展开后再次覆盖
        array = [].concat(...array)
    }
    return array;
}

console.log(Flatten(arr));//[ 1, 2, 3, 4, 5 ]

6. 递归函数

递归函数同样用到了Array.isArray方法,如果发现数组中存在数组嵌套就递归调用进行展开。

const arr = [1, [2, [3, [4, [5]]]]];

function fn(array) {  
    let a = [];
    for (let i = 0; i < array.length; i++){
        // 存在数组就进行递归调用
        if (Array.isArray(array[i])) {
            a = a.concat(fn(array[i]));
        } else { // 不存在直接push
            a.push(array[i]);
        }
    }
    return a;
}

console.log(fn(arr)); //[1,2,3,4,5]

7. reduce思想

reduce思想是传递一个空数组作为接收对象,同时也使用了递归思想,将数组使用递归进行展开,最后返回一维数组。

const arr = [1, [2, [3, [4, [5]]]]];

function Flatten(array) {
    return array.reduce((pre, cur) => {
        // 判断是否存在数组,存在就递归,不存在直接push
        return pre.concat(Array.isArray(cur)?Flatten(cur):cur)
    },[]) //传递空数组作为接收对象
}

console.log(Flatten(arr));[1, 2, 3, 4, 5]

写在最后

数组扁平化可以说是相对简单的一个方法,方法也是多种多样,在这也只是罗列了一下我熟悉的几种方法。有更好的方法也欢迎各位大牛在评论区指点。

我是江河,前端实习生一枚,欢迎各位大佬滴滴,文章如有不正之处敬请斧正!