实现数组扁平化flat方法
手写实现数组的flat方法,将多维数组转换为一维数组,支持指定扁平化深度
问题
数组扁平化是指将嵌套的多维数组转换为一维数组的过程。例如 [1, [2, [3, 4]]] 扁平化后变为 [1, 2, 3, 4]。需要实现一个 flat 方法,支持指定扁平化的深度,当深度为 Infinity 时完全扁平化。
解答
方法一:递归实现
/**
* 数组扁平化 - 递归实现
* @param {Array} arr - 需要扁平化的数组
* @param {number} depth - 扁平化深度,默认为1
* @returns {Array} 扁平化后的数组
*/
function flat(arr, depth = 1) {
// 如果深度为0,直接返回原数组的浅拷贝
if (depth === 0) {
return arr.slice();
}
return arr.reduce((result, item) => {
// 如果当前项是数组且深度大于0,递归处理
if (Array.isArray(item)) {
result.push(...flat(item, depth - 1));
} else {
result.push(item);
}
return result;
}, []);
}
方法二:迭代实现
/**
* 数组扁平化 - 迭代实现
* @param {Array} arr - 需要扁平化的数组
* @param {number} depth - 扁平化深度,默认为1
* @returns {Array} 扁平化后的数组
*/
function flat(arr, depth = 1) {
let result = arr.slice();
// 根据深度循环处理
while (depth > 0 && result.some(item => Array.isArray(item))) {
result = [].concat(...result);
depth--;
}
return result;
}
方法三:栈实现(支持无限深度)
/**
* 数组扁平化 - 栈实现
* @param {Array} arr - 需要扁平化的数组
* @param {number} depth - 扁平化深度,默认为1
* @returns {Array} 扁平化后的数组
*/
function flat(arr, depth = 1) {
const stack = arr.map(item => [item, 0]); // [元素, 当前深度]
const result = [];
while (stack.length) {
const [item, currentDepth] = stack.pop();
// 如果是数组且未达到指定深度,继续展开
if (Array.isArray(item) && currentDepth < depth) {
// 逆序入栈,保证顺序正确
for (let i = item.length - 1; i >= 0; i--) {
stack.push([item[i], currentDepth + 1]);
}
} else {
result.unshift(item); // 从前面插入保证顺序
}
}
return result;
}
使用示例
// 示例1:基本使用
const arr1 = [1, [2, [3, 4]]];
console.log(flat(arr1)); // [1, 2, [3, 4]]
console.log(flat(arr1, 1)); // [1, 2, [3, 4]]
console.log(flat(arr1, 2)); // [1, 2, 3, 4]
// 示例2:完全扁平化
const arr2 = [1, [2, [3, [4, [5]]]]];
console.log(flat(arr2, Infinity)); // [1, 2, 3, 4, 5]
// 示例3:包含空位的数组
const arr3 = [1, 2, [3, 4, [5, 6, [7, 8]]]];
console.log(flat(arr3, 2)); // [1, 2, 3, 4, 5, 6, [7, 8]]
// 示例4:混合类型
const arr4 = [1, 'a', [2, 'b', [3, 'c']], null, undefined];
console.log(flat(arr4, 2)); // [1, 'a', 2, 'b', 3, 'c', null, undefined]
// 示例5:空数组和深度为0
const arr5 = [1, [2, 3]];
console.log(flat(arr5, 0)); // [1, [2, 3]]
console.log(flat([], Infinity)); // []
关键点
- 递归终止条件:当深度为 0 时停止递归,或者当前元素不是数组时直接返回
- 深度控制:每递归一层,深度减 1,确保只扁平化指定层数
- 数组判断:使用
Array.isArray()准确判断是否为数组类型 - reduce 方法:利用
reduce累积结果,配合扩展运算符...展开数组 - concat 方法:
[].concat(...result)可以将数组中的第一层数组元素展开 - 边界处理:处理空数组、深度为 0、深度为 Infinity 等特殊情况
- 性能考虑:递归方法代码简洁但可能栈溢出,迭代方法性能更好,栈方法适合深层嵌套
- 保持顺序:确保扁平化后元素的顺序与原数组一致
目录