标准答案

  1. 最简单方式是使用原生 Array.prototype.flat(depth)。
  2. 手写时可以递归遍历数组,遇到数组且 depth 大于 0 就继续展开。
  3. 非数组元素应原样放入结果,不能误删 false、0、空字符串等值。
  4. depth 为 0 时不再展开,Infinity 可以表示完全展开。
  5. 深层或超大数组要注意递归调用栈,可以考虑显式栈迭代实现。

题目解析

扁平化题目看起来简单,但面试里通常会追问边界。比如只展开一层还是全部展开,如何处理 depth,如何保留非数组值,是否需要模拟原生 flat 对稀疏数组的行为。

递归实现最直观,适合说明思路。但如果嵌套极深,递归可能栈溢出;生产代码如果真的要处理不可信大数据,就要考虑迭代方案。

不要用 JSON.stringify 这类旁路方式处理,它会改变数据类型,也处理不了函数、undefined、Symbol 等值。

代码示例

递归版可以清楚表达按深度展开的规则。

JavaScript
function flatten(array, depth = 1) {
  const result = []

  for (const item of array) {
    if (Array.isArray(item) && depth > 0) {
      result.push(...flatten(item, depth === Infinity ? Infinity : depth - 1))
    } else {
      result.push(item)
    }
  }

  return result
}

常见误区

  • 默认全部展开,却没有说明 depth 规则。
  • 用 filter(Boolean) 或类似写法,误删 0、false、空字符串。
  • 只写递归版本,不知道深层数组可能触发调用栈问题。

作者信息