手撸 JS flat 和 flatMap 函数
起因
之前经常在用 lodash
的 flatten
等方法,一直没注意原来 es6
现在自带了 flat
和 flatMap
函数,看来手册还是要再多翻翻,回顾回顾了。既然偶然看到了自带方法,那就自己手撸一个惩罚下自己(虽然函数实现非常简单),顺便做个记录;
flat
用法
flat
函数是在 Array.prototype
中定义,属于 Array
的原型方法,因此我们可以直接像下面这样用:
const arr = [1, 2, 3, 4, [1, 2, 3], [[1, 2], [1, 2, [1, 2]]]];
console.log( arr.flat() );
// [ 1, 2, 3, 4, 1, 2, 3, [ 1, 2 ], [ 1, 2, [ 1, 2 ] ] ]
flat
接受一个参数,参数默认为 1 ,是指剥掉的层数,比如原来是 3 维的,剥掉 1 层,就是 2 维了,参数也可以是 Infinity
无穷, 无穷则最终转成 1 维, 如下使用方法;
const arr = [1, 2, 3, 4, [1, 2, 3], [[1, 2], [1, 2, [1, 2]]]];
// 剥掉两层
console.log(arr.flat(2))
// [ 1, 2, 3, 4, 1, 2, 3, 1, 2, 1, 2, [ 1, 2 ] ]
console.log(arr.flat(Infinity))
// [ 1, 2, 3, 4, 1, 2, 3, 1, 2, 1, 2, 1, 2]
由于 flat
函数是 Array
的原型链方法,因此也可以直接使用 Array.prototype.flat
来操作数组,如:
const arr = [1, 2, 3, 4, [1, 2, 3], [[1, 2], [1, 2, [1, 2]]]];
console.log( Array.prototype.flat.call(arr,1) );
// [ 1, 2, 3, 4, 1, 2, 3, [ 1, 2 ], [ 1, 2, [ 1, 2 ] ] ]
手撸 flat
函数
说实话这种函数几乎没有什么难度,我就直接上代码了:
const flat = (arr, level = 1) => {
const res = [];
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i]) && level > 0) {
res.push(...flat(arr[i], level - 1));
} else res.push(arr[i]);
}
return res;
}
const arr = [1, 2, 3, 4, [1, 2, 3], [[1, 2], [1, 2, [1, 2]]]];
console.log(flat(arr, 2));
// [ 1, 2, 3, 4, 1, 2, 3, 1, 2, 1, 2, [ 1, 2 ] ]
console.log(flat(arr, Infinity));
// [ 1, 2, 3, 4, 1, 2, 3, 1, 2, 1, 2, 1, 2]
flatMap
函数使用
flatMap
就类似 map
,对每一个元素做自定义处理,比如:
const arr = [1, 2, 3, 4, [1, 2, 3], [[1, 2], [1, 2, [1, 2]]]];
console.log( arr.flatMap(x => [5,6] ));
// [ 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6 ]
回调函数
返回的内容应该是一个数组,然后把元素连接在一起。
手撸 flatMap
函数
这个函数其实比之前的 flat
更简单,原理就是 map
的函数式编程原理,简单回调即可:
const flatMap = (arr, cb) => {
const res = [];
for (let i = 0; i < arr.length; i++) {
res.push(...cb(arr[i], i));
}
return res;
}
const arr = [1, 2, 3, 4, [1, 2, 3], [[1, 2], [1, 2, [1, 2]]]];
console.log( arr.flatMap(x => flat(x,2)));
// [ 1, 2, 3, 1, 2, 1, 2, 1, 2 ]
console.log( flatMap(arr, x => flat(x,2)));
// [ 1, 2, 3, 1, 2, 1, 2, 1, 2 ]
总结
函数本身并没有什么难度,只是不知道有这个函数的存在有点懵~,手册还是没有翻到位,改天继续翻。