Lodash 源码阅读-flattenDepth
概述
flattenDepth
函数可以控制数组"压扁"的层数。比如 [1, [2, [3, [4]], 5]]
,如果深度是 1,就变成 [1, 2, [3, [4]], 5]
;如果深度是 2,就变成 [1, 2, 3, [4], 5]
。这个函数比 flatten
更灵活,可以精确控制要压扁几层。
前置学习
依赖函数
- baseFlatten:实际干活的函数,处理数组扁平化的核心逻辑
- toInteger:把值转成整数,用来处理深度参数
技术知识
- 数组操作:数组的基本操作和嵌套数组的概念
- 递归:函数自己调用自己的基本概念
- 参数默认值:函数参数默认值的处理
源码实现
javascript
/**
* Recursively flatten `array` up to `depth` times.
*
* @static
* @memberOf _
* @since 4.4.0
* @category Array
* @param {Array} array The array to flatten.
* @param {number} [depth=1] The maximum recursion depth.
* @returns {Array} Returns the new flattened array.
* @example
*
* var array = [1, [2, [3, [4]], 5]];
*
* _.flattenDepth(array, 1);
* // => [1, 2, [3, [4]], 5]
*
* _.flattenDepth(array, 2);
* // => [1, 2, 3, [4], 5]
*/
function flattenDepth(array, depth) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
depth = depth === undefined ? 1 : toInteger(depth);
return baseFlatten(array, depth);
}
实现思路
flattenDepth
的实现很简单:
- 先检查数组是不是空的或
null
,如果是就返回空数组 - 处理深度参数:
- 如果没传深度参数,默认用 1
- 如果传了,就用
toInteger
转成整数
- 调用
baseFlatten
函数,告诉它要压扁几层 baseFlatten
会遍历数组的每个元素:- 如果元素是数组且深度大于 0,就递归处理这个元素,深度减 1
- 如果元素不是数组或深度为 0,就直接放到结果里
- 返回压扁后的新数组
源码解析
空值检查
javascript
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
这行代码做了两件事:
- 检查数组是不是
null
或undefined
,如果是就把长度设为 0 - 如果长度是 0(空数组或
null
),直接返回空数组
深度参数处理
javascript
depth = depth === undefined ? 1 : toInteger(depth);
这行代码处理深度参数:
- 如果没传深度参数,默认用 1
- 如果传了,就用
toInteger
转成整数,这样即使传的是字符串或小数也能正确处理
baseFlatten 的调用
javascript
return baseFlatten(array, depth);
这里传了两个参数:
- 第一个是要处理的数组
- 第二个是深度参数,告诉
baseFlatten
要压扁几层
baseFlatten
函数会遍历数组的每个元素,根据深度参数决定是否继续递归处理嵌套数组。
总结
flattenDepth
函数虽然简单,但有几个重要的特点:
-
控制压扁层数 - 可以精确控制要压扁几层,比
flatten
更灵活 -
不修改原数组 - 返回新数组,保持原数组不变
-
处理边界情况 - 能正确处理空数组、
null
等特殊情况 -
支持多种输入 - 通过
toInteger
可以处理各种类型的深度参数
这个函数对处理嵌套数据结构非常有用,它既能满足一定程度的扁平化需求,又不会像 flattenDeep
那样过度扁平化,让开发者可以精确控制处理的层级。