持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
前言
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
本文记叙手动实现的基本思路和代码。
基本思路
思路其实不复杂,很简单,就是遍历数组:
- 如果子元素也是数组,那么根据扁平化深度的需求,确定是否继续遍历子元素,展开扁平化;
- 如子元素不是数组,直接返回子元素本身即可。
但是因为 flat 扁平化数组后,不会改变子元素展开后位置,如:
flat([1, [2, 3], 4])
// [1, 2, 3, 4]
所以使用递归的方式来实现比较简单明了,如果使用循环和栈等非递归方式实现,会比较麻烦,需要使用变量缓存的信息数据比较多。
代码
首先,定义函数,函数接受两个参数:
-
- 需要被扁平化的数组
array;
- 需要被扁平化的数组
-
- 扁平化的深度
depth; 还必须返回新的数组,所以定义的代码如下:
- 扁平化的深度
/**
* 手写 flat 函数 递归实现
* @param { Array<any> } array 需要被扁平化的数组
* @param { number } depth 扁平化深度,默认为1
* @returns { Array<any> }
*/
function myFlat_recursion (array: Array<any>, depth = 1): Array<any> {
// 返回结果的数组
const returnArray = []
return returnArray
}
接着,对参数进行检测,检测的条件有三个:
-
- array 必须为数组
-
- depth 必须为 number
-
- depth 必须大于等于 0 代码如下:
/**
* 参数检测,如果参数错误,返回 `array` 本身,以下参数条件
* 1. array 必须为数组
* 2. depth 必须为 number
* 3. depth 必须大于等于 0
*/
if (!Array.isArray(array) || typeof depth !== 'number' || depth < 0) {
return array
}
然后就是遍历 array ,出现以下几种情况:
-
depth - 1如果大于等于0,并且子元素item是数组,则递归调用myFlat_recursion,把子元素和depth - 1作为参数入参,把返回结果放入当前的返回数组中;
-
- 其他情况直接将子元素
item放入当前的返回数组中。 代码如下:
- 其他情况直接将子元素
// 返回结果的数组
const returnArray = []
// 递归调用时的扁平化深度
const newDepth = depth - 1
for (let i = 0, len = array.length; i < len; i++) {
const item = array[i]
// 判断,确定 returnArray.push 时的值
Array.isArray(item) && newDepth >= 0 ? returnArray.push(...myFlat_recursion(item, newDepth)) : returnArray.push(item)
}
完整代码如下:
function myFlat_recursion (array: Array<any>, depth = 1): Array<any> {
if (!Array.isArray(array) || typeof depth !== 'number' || depth < 0) {
return array
}
const returnArray = []
const newDepth = depth - 1
for (let i = 0, len = array.length; i < len; i++) {
const item = array[i]
Array.isArray(item) && newDepth >= 0 ? returnArray.push(...myFlat_recursion(item, newDepth)) : returnArray.push(item)
}
return returnArray
}
测试一把:
const arr = [1, [2, 3, [4, 5, [12, 3, "zs"], 7, [8, 9, [10, 11, [1, 2, [3, 4]]]]]]]
const depth = Number.MAX_SAFE_INTEGER
console.log('Array.prototype.flat:', arr.flat(depth))
console.log('my flat recursion:', myFlat_recursion(arr, depth))
如果 const depth = 2,结果如下: