我了解的数组扁平化的方法有三种。
第一种,我们自己实现
function flat(arr){
var res = [];
for(let el of arr){
if(Array.isArray(el)){
res = res.concat(flat(el));
}else{
res.push(el);
}
}
return res;
}
let arr = [1,[2,[3,4]]];
flat(arr); // [1, 2, 3, 4]
第二种,利用generator
这是一种非常巧妙的方式,使用generator来创建一个迭代器对象生成函数,在这个generator中对于元素仍然是数组的元素,继续使用generator创建迭代器对象,同时使用yield*对其进行遍历,如此深入。这个方法在阮一峰老师《ECMAScript6 入门》中有介绍。
function* _flat(el){
if(Array.isArray(el)){
for(let item of el){
yield* _flat(item);
}
}else{
yield el;
}
}
function flat(arr){
return [..._flat(arr)];
}
第三种,lodash的baseFlatten
在lodash中和数组扁平化相关的方法有三个,flatten()
, flattenDepth()
和flattenDeep()
。三个方法的区别只是扁平化的程度不同。实际实现上都是对baseFlatten()
函数的包装。
其中baseFlatten()
的核心代码如下:
function baseFlatten(arr, depth, result){
result || (result=[]);
if(arr === null) return result;
for(const val of arr){
if(depth>0 && Array.isArray(val)){
if(depth>1){
baseFlatten(val, depth-1, result);
}else{
result.push(...val);
}
}else{
result[result.length] = val;
}
}
return result;
}
实际源码略有区别,可以参考源码。