数组扁平化 ,是指将一个嵌套的多维数组,按照指定的深度(depth) ,逐层剥离外层的 [] 包装,将其转换为嵌套层数更少(直至完全一维)的数组结构。
深度(depth)控制着扁平化的程度:
-
depth = 1 :只剥掉最外面一层
[]。例如[1, [[2, 3], 4]]→[1, [2, 3], 4]。 -
depth = 2 :剥掉两层
[]。例如[1, [[2, 3], 4]]→[1, 2, 3, 4]。 -
depth = Infinity:无论嵌套多深,全部剥光,彻底变成一维数组。
代码
手撕的思路也就是一层一层剥开。要先判断是否是数组以及depth是否到0了,如果是数组且depth>0,就进行递归拼接;如果不满足条件,就直接push到结果数组里。
javascript
function myFlat(arr, depth = 1) {
let res = []
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i]) && depth) {
// concat把多个数组拼接起来,返回新数组
res = res.concat(myFlat(arr[i], depth - 1))
} else {
res.push(arr[i])
}
}
return res
}
样例演示
假设调用 flat(arr, 1)(扁平化 1 层):
-
初始化 :
let res = [],开始遍历外层数组。 -
i=0 :
arr[0] = 1,不是数组,else分支,res.push(1)→res = [1]。 -
i=1 :
arr[1] = [2, [3, 4]],是数组且depth = 1(真值),进入递归。-
调用
flat([2, [3, 4]], 0)(注意:depth - 1 = 0)。 -
在递归内部:遍历
[2, [3, 4]]。-
2不是数组 → 推入。 -
[3, 4]是数组,但此时depth = 0(假值),if条件不成立,走else,直接把整个[3, 4]推入。
-
-
递归返回
[2, [3, 4]]。 -
外层执行
res = res.concat([2, [3, 4]])→res = [1, 2, [3, 4]]。
-
-
遍历结束 ,返回
[1, 2, [3, 4]]。
Tips
1.flat() 在执行时会自动移除数组中的空位(empty),但会保留 undefined 和 null。
javascript
const arr = [1, , 2, [3, , 4]];
console.log(arr.flat()); // [1, 2, 3, 4]
这是因为原生 flat 在遍历时,会跳过空位(不进入循环),所以空位直接被忽略了。
2.flat() 不修改原数组,而是返回一个新数组,符合 React/Vue 等框架的"不可变数据"原则。