五分钟学习数组扁平化(flat)

661 阅读2分钟

在面试和日常学习中,或许都有听过数组扁平化这个词,那么它到底是个啥东西呢?

概念

按个人的理解,数组扁平化就是将多层嵌套数组向外提到同一层中?

比如 [1, 2, [3, 4]] => [1, 2, 3, 4]

超过两层的时候 [1, 2, [3, 4, [5, 6]]] => [1, 2, 3, 4, 5, 6]

前端实现

  1. 正则
const arr = [1, 2, [3, 4, [5, 6]]]

const str = JSON.stringify(arr).replace(/[\[\]]/g, '') //  1, 2, 3, 4, 5, 6

const newArr = JSON.parse('[' + str + ']') // [1, 2, 3, 4, 5, 6]

正则可以很方便处理数组扁平化,它的缺点在于 JSON 的序列号/解析,还有正则都是比较耗费性能的。还有个局限性是不能自定义扁平化的层级

  1. 递归

使用递归我们可以通过参数设定扁平化的层级

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

arr.flat(1) // [1, 2, 3, 4, [5, 6]]

arr.flat(2) // [1, 2, 3, 4, 5, 6]

下面为实现代码

/**
 * 数组扁平化
 * @param {Number} depth 扁平化层级
 * @return 数组副本
 * /
Array.prototype.flat = function flat(depth = 1) {
    return depth > 0 ? this.reduce((pre, next) => 
        pre.concat(Array.isArray(next) ? next.flat(depth - 1) : next),
    []) : this.slice()
}

讲讲函数实现的思路,让大家更好理解一些

  1. 判断参数扁平化层级,如果小于1则直接返回数组副本

  2. 遍历当前数组,其实使用for或者其它数组方法都行(使用reduce遍历的好处在于可以设置初始值[],不用声明新变量)

  3. 判断当前元素是否为数组,是数组则进入递归,扁平化该元素(注意depth - 1)

  4. 返回处理结果

函数效果演示

const a = [
    2, 3, 4, 
        [5, 6, 
            [ 7, 8, 
                [ 9, 10, 11]
            ]
        ],
    12, 
        [13, 14, 
            [15, 16]
        ], 
    17, 
        [18, 19]
]

a.flat(-1) // [2,3,4,[5,6,[7,8,[9,10,11]]],12,[13,14,[15,16]],17,[18,19]]
a.flat(0)  // [2,3,4,[5,6,[7,8,[9,10,11]]],12,[13,14,[15,16]],17,[18,19]]
a.flat(1)  // [2,3,4,5,6,[7,8,[9,10,11]],12,13,14,[15,16],17,18,19]
a.flat(2)  // [2,3,4,5,6,7,8,[9,10,11],12,13,14,15,16,17,18,19]
a.flat(3)  // [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
a.flat(4)  // [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
a.flat(Infinity) // [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]

参考


欢迎来前端学习打卡群一起学习~516913974