数组扁平化实现
用递归、reduce、flat 三种方式实现数组扁平化
问题
将多层嵌套的数组转换为一维数组,例如 [1, [2, [3, 4]]] 转换为 [1, 2, 3, 4]。
解答
1. 递归实现
function flatten(arr) {
let result = [];
for (let item of arr) {
if (Array.isArray(item)) {
// 递归处理嵌套数组,合并结果
result = result.concat(flatten(item));
} else {
result.push(item);
}
}
return result;
}
// 测试
console.log(flatten([1, [2, [3, 4]]])); // [1, 2, 3, 4]
2. reduce 实现
function flatten(arr) {
return arr.reduce((acc, item) => {
// 是数组就递归,否则直接拼接
return acc.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
// 测试
console.log(flatten([1, [2, [3, [4, 5]]]])); // [1, 2, 3, 4, 5]
3. 使用 flat 方法
// Infinity 表示展开任意深度
const result = [1, [2, [3, [4]]]].flat(Infinity);
console.log(result); // [1, 2, 3, 4]
// 指定展开深度
console.log([1, [2, [3]]].flat(1)); // [1, 2, [3]]
console.log([1, [2, [3]]].flat(2)); // [1, 2, 3]
4. 支持指定深度的实现
function flatten(arr, depth = 1) {
if (depth < 1) return arr.slice();
return arr.reduce((acc, item) => {
if (Array.isArray(item) && depth > 0) {
return acc.concat(flatten(item, depth - 1));
}
return acc.concat(item);
}, []);
}
// 测试
console.log(flatten([1, [2, [3, [4]]]], 2)); // [1, 2, 3, [4]]
console.log(flatten([1, [2, [3, [4]]]], Infinity)); // [1, 2, 3, 4]
5. 迭代实现(栈)
function flatten(arr) {
const stack = [...arr];
const result = [];
while (stack.length) {
const item = stack.pop();
if (Array.isArray(item)) {
// 数组元素重新入栈
stack.push(...item);
} else {
// 非数组元素加入结果(头部插入保持顺序)
result.unshift(item);
}
}
return result;
}
// 测试
console.log(flatten([1, [2, [3, 4]]])); // [1, 2, 3, 4]
关键点
Array.isArray()判断是否为数组- 递归是最直观的思路,但要注意调用栈深度
reduce写法更简洁,本质还是递归flat(Infinity)是最简单的方案,但要注意兼容性- 迭代实现用栈模拟递归,避免栈溢出
目录