很多时候我们需要处理嵌套数组,但环境不支持 flat() 或者想更精细地控制过程。核心思路其实就两点:遍历元素,遇到数组就继续拆解,否则保留。下面分享三种落地方案,从易到难,覆盖不同场景。
递归实现(最直观,适合常规场景)
递归的核心在于'自调用'。遍历数组的每一个元素,如果当前项是数组且未达到指定深度,就再次调用自身;如果不是数组,直接加入结果。这种方式代码可读性最高,新手最容易上手。
function flattenArray(arr, depth = Infinity) {
const result = [];
arr.forEach(item => {
if (Array.isArray(item) && depth > 0) {
result.push(...flattenArray(item, depth - 1));
} else {
result.push(item);
}
});
return result;
}
// 测试:完全扁平化
console.log(flattenArray([1, [2, [3]], 4]));
// 输出:[1, 2, 3, 4]
这里有个细节要注意:depth 参数控制了扁平化的层级,默认 Infinity 表示彻底打平。配合扩展运算符 ...,可以把递归返回的子数组元素逐个展开,避免二次嵌套。
迭代实现(防栈溢出,适合深层嵌套)
如果数组嵌套极深,递归可能会触发调用栈溢出错误。这时候用循环加栈的方式更稳妥。利用栈'后进先出'的特性,把待处理的子数组压入栈中,直到栈空为止。
function flattenArrayIterative(arr) {
const stack = [...arr];
const result = [];
while (stack.length) {
const item = stack.pop();
if (Array.(item)) {
stack.(...item);
} {
result.(item);
}
}
result.();
}
.(([, [, [, ], ]]));

