flat介绍
flat()
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
const arr = [1, 2, [3, 4, [5, 6, [7]]], 8];
console.log(arr.flat(Infinity)); //[1,2,3,4,5,6,7,8]
console.log(arr.flat(2)); //[1,2,3,4,5,6,[7],8]
手写:
function flat(arr,n) {
let times = 0; //利用闭包记住times
// 遍历数组
function flatten(arr) {
const result = [];
arr.forEach(item => {
if (Array.isArray(item)) {
// 如果元素是数组则再次进行flatten操作且times+1
if (times >= n) {
//递归次数用尽,直接把元素推入数组
result.push(item);
}
times++;
result.push(...flatten(item));
} else {
result.push(item);
}
});
return result;
}
return flatten(arr);
}
测试:
const arr = [1, 2, [3, 4,[1,3,[3]]], 8];
console.log(flat(arr,2)); //[1, 2, 3, 4, 1, 3, [3], 8]
console.log(flat(arr,3)); //[1, 2, 3, 4, 1, 3, 3, 8]
法二
上面实在太复杂了,使用reduce 和 concat 会大大降低代码量,不过核心还是要靠递归!
function flat(arr,dep=1) {
return arr.reduce((acc, cur) => {
return acc.concat(Array.isArray(cur)&&dep>0 ? flat(cur,dep-1):[cur])
},[])
}
console.log(flat(arr,1));
带 * 号注释的代码的意思是:如果当前的val是数组且dep(扁平深度)大于0则递归,反之则直接concat 当前的[val]。
为啥让当前的val变成了数组 [val],因为 concat它会减少一层数组,如 [4].concat([1,2])
,结果是[4,1,2]
而不是[4,[1,2]]
。