在面试和日常学习中,或许都有听过数组扁平化这个词,那么它到底是个啥东西呢?
概念
按个人的理解,数组扁平化就是将多层嵌套数组向外提到同一层中?
比如 [1, 2, [3, 4]] => [1, 2, 3, 4]
超过两层的时候 [1, 2, [3, 4, [5, 6]]] => [1, 2, 3, 4, 5, 6]
前端实现
- 正则
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 的序列号/解析,还有正则都是比较耗费性能的。还有个局限性是不能自定义扁平化的层级
- 递归
使用递归我们可以通过参数设定扁平化的层级
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则直接返回数组副本 -
遍历当前数组,其实使用
for或者其它数组方法都行(使用reduce遍历的好处在于可以设置初始值[],不用声明新变量) -
判断当前元素是否为数组,是数组则进入递归,扁平化该元素(注意depth - 1)
-
返回处理结果
函数效果演示
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