flat()
先用es6的语法看看flat函数的功能是什么
let arr = [1,2,[3,4,[5,6],[7],[8,[9]]]].flat(5)
let arr2 = [1,2,[3,4,[5,6],[7],[8,[9]]]].flat()
console.log(arr) //[1,2,3,4,5,6,7,8,9]
console.log(arr2) //[1, 2, 3, 4, Array(2), Array(1), Array(2)]
所以很明显,flat函数的功能就是降维(“拉平”数组维度),且默认值为1
let arr3 = [1,2,[3,4, ,5,6,null,7,8,undefined,9]].flat()
console.log(arr3) //[1, 2, 3, 4, 5, 6, null, 7, 8, undefined, 9]
接下来看arr3数组的值以及输出内容,可以看到4和5之间有一个空位,但是输出却没有这个空位。
所以flat函数有一个特性是可以跳过空位,但是null和undefined还是会被保留。
当然如果不知道数组深度是多少,也可以传Infinity值
let arr = [1,2,[3,4,[5,6],[7],[8,[9]]]].flat(Infinity)
console.log(arr) //[1,2,3,4,5,6,7,8,9]
简单实现
Array.prototype.myFlat = function (depth = 1) {
// 用reduce方法获取结果,传入默认值空数组[]
return this.reduce((result, item) => {
if (depth > 0 && Object.prototype.tostring.call(item) == '[object Array]') {
// 如果depth大于0(为有效值)且下个数组项为数组则进入递归
result = [
...result,
...item.myFlat(depth - 1)
]
} else {
// 如果该数组项不为数组,则直接push
result.push(item)
}
return result
}, [])
}
// 测试一下
let arr = [1,2,[3,4,[5,6],[7],[8,[9]]]].flat(5)
let arr2 = [1,2,[3,4,[5,6],[7],[8,[9]]]].flat()
console.log(arr) //[1,2,3,4,5,6,7,8,9]
console.log(arr2) //[1, 2, 3, 4, Array(2), Array(1), Array(2)]
// 和原生的结果是一样的
flatMap()
es6还有一个flatMap()方法,这边可以了解一下。
flatMap()方法会对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。
// 相当于 [[2, 4], [3, 6], [4, 8]].flat()
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]
flatMap()只能展开一层数组。
// 相当于 [[[2]], [[4]], [[6]], [[8]]].flat()
[1, 2, 3, 4].flatMap(x => [[x * 2]])
// [[2], [4], [6], [8]]
上面代码中,遍历函数返回的是一个双层的数组,但是默认只能展开一层,因此flatMap()返回的还是一个嵌套数组。
flatMap()方法的参数是一个遍历函数,该函数可以接受三个参数,分别是当前数组成员、当前数组成员的位置(从零开始)、原数组。
arr.flatMap(function callback(currentValue[, index[, array]]) {
// ...
}[, thisArg])
flatMap()方法还可以有第二个参数,用来绑定遍历函数里面的this
let obj = {
a: 1
}
console.log([1, 2, 3, 4].flatMap(function (x, index) {
return [index, x + this.a]
}, obj))
// [0, 2, 1, 3, 2, 4, 3, 5]