Lodash 源码阅读-flattenDeep
概述
flattenDeep
函数用于将任意深度的嵌套数组完全"扁平化",将所有元素提取到一个单层数组中。无论数组嵌套多少层,都能将其转换为一维数组,便于后续处理。
前置学习
依赖函数
- baseFlatten:实现数组扁平化的核心函数
技术知识
- 数组操作:数组的基本操作和嵌套数组概念
- 递归:递归算法的基本原理
- 无穷大常量 :JavaScript 中的
Infinity
常量
源码实现
javascript
/**
* Recursively flattens `array`.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to flatten.
* @returns {Array} Returns the new flattened array.
* @example
*
* _.flattenDeep([1, [2, [3, [4]], 5]]);
* // => [1, 2, 3, 4, 5]
*/
function flattenDeep(array) {
var length = array == null ? 0 : array.length;
return length ? baseFlatten(array, INFINITY) : [];
}
实现思路
flattenDeep
的实现非常直接:先检查数组是否有效,然后调用 baseFlatten
函数进行完全扁平化。传给 baseFlatten
的 INFINITY
参数表示无限深度,确保无论嵌套多少层都能完全扁平化。
源码解析
参数检查
javascript
var length = array == null ? 0 : array.length;
return length ? baseFlatten(array, INFINITY) : [];
这行代码处理边界情况:
- 如果数组为
null
或undefined
,返回空数组 - 如果数组为空,返回空数组
- 否则调用
baseFlatten
进行扁平化
核心扁平化逻辑
javascript
baseFlatten(array, INFINITY);
baseFlatten
函数的工作流程:
- 遍历数组中的每个元素
- 如果元素是可扁平化的(数组或类数组):
- 递归调用
baseFlatten
处理这个元素 - 深度参数
INFINITY
确保无限递归
- 递归调用
- 如果元素不可扁平化,直接添加到结果数组
应用场景
处理嵌套数据
将多层嵌套的数据结构完全扁平化:
javascript
const nested = [1, [2, [3, [4, [5]]], 6]];
const flat = _.flattenDeep(nested);
// => [1, 2, 3, 4, 5, 6]
总结
flattenDeep
函数体现了以下设计原则:
- 完整性:支持任意深度的嵌套数组扁平化
- 不可变性:创建新数组而非修改原数组
- 健壮性:处理各种边界情况(null、空数组等)
- 性能考量:注意深度递归可能导致的栈溢出问题
这个函数在处理复杂嵌套数据结构时特别有用,但要注意避免处理过深的嵌套结构,以防栈溢出。对于深度可控的场景,可以考虑使用 flattenDepth
函数并指定合适的深度。