算法 - 数组扁平化 (Flatten Array)
1. 题目
实现一个函数,把可能嵌套多维的数组「摊平」成一维数组。前端面试手写题常客。
示例:
1 | flatten([1, [2, [3, [4]], 5]]) -> [1, 2, 3, 4, 5] |
进阶要求:支持指定「扁平化深度」 flatten(arr, depth),depth 表示要展开几层,Infinity 表示全部展开(对齐 Array.prototype.flat 的行为)。
2. 解题思路
嵌套结构 = 天然的递归场景。核心逻辑一句话:
遍历数组,遇到元素是数组就递归展开并把结果拼接,否则直接收集。
对于「限深度」版本,给递归加一个 depth 参数,每下钻一层 depth - 1,为 0 时不再展开直接返回当前层拷贝。
可以用多种流派展示功力:
reduce+ 递归(最能体现思路,面试首推)。展开运算符 + 递归。
while + some + concat(检测是否还有数组,逐步拉平)。toString的副作用 trick(不推荐,会把 null 变空串)。生成器
function*(工程优雅,可迭代惰性展开)。时间复杂度:
O(N),N 为所有层级元素总数。空间复杂度:
O(N)+ 递归栈O(最大深度)。
3. TypeScript 实现
3.1 基础版:reduce + 递归
1 | type Nested = number | Nested[]; |
3.2 进阶版:支持 depth(对齐 Array.flat)
1 | function flattenDepth(arr: Nested[], depth = 1): number[] { |
3.3 生成器版:可迭代、优雅
1 | function* genFlat(arr: Nested[]): Generator<number> { |
1 | // 测试 |
4. 面试延伸
flatvsflatMap:flatMap只展开一层且能map,性能略优于map().flat()。- 对象/字符串边界:真实项目要判
Array.isArray,别用typeof === 'object',否则null、字典对象会被误展开。 - 保持类型:泛型进阶
type Flat<T> = ...能在类型层面推导扁平结果,展示 TS 功底。 - 一句话:能默写递归版是底线,能顺手写出限深度 + 生成器版就是加分项。
难度:简单 | 前端手写题 Top 10 | 递归基本功