前言
在聊这个问题之前,我们先得理解什么是扁平化?其实扁平化就是字面意思,当我们的数组中嵌套了很多的数组时,我们将其变成一维数组的方法,这就是扁平化,接下来我们来聊聊几种扁平化的方法。
arr.flat()
我们都知道数组身上有许多自带的方法,比如map,filter等遍历方法,除了这些方法之外,它身上还自带了一个可以扁平化数组的方法flat()
,它的里面可以传递一个参数,想要将数组扁平几维度就传入几,下面我们来看个例子:
js
let arr = [1, [2, [3, 4]]]
console.log(arr.flat(1));
console.log(arr.flat(2));
// 输出:
[ 1, 2, [ 3, 4 ] ]
[ 1, 2, 3, 4 ]
这时候就有一个问题了,如果我们不确定数组中嵌套了几层,那么如何将其扁平化为一维数组呢?我们都知道里面传入的数字就代表扁平化几次,那么我们一直扁平下去直到扁平成一维就能解决这个问题,这时候我们直接传入Infinity
。
js
let arr = [1, [2, [3, 4, [5]]]]
console.log(arr.flat(Infinity));
// 输出:
[ 1, 2, 3, 4, 5 ]
toString()
我们都知道在js中每个类型都有自己的一个toString()
方法,数组身上的toString()
方法可以直接将数组中的元素都变成字符串并且以逗号拼接起来,除了这个效果之外,它还能实现一个扁平化的效果,我们来看一个示例:
js
let arr = [1, [2, [3, 4, [5]]]]
console.log(arr.toString());
// 输出:
// 1,2,3,4,5
这时候我们只需要再使用split()
方法将字符串转化为数组即可。
js
let arr = [1, [2, [3, 4, [5]]]]
function flatten3(arr) {
return arr.toString().split(',').map(item => +item)
}
tips:这个方法是个取巧的方法,只能处理里面是原始类型的数组
some() + concat()
在介绍这个方法之前,我们先来了解一下数组身上自带的两个方法some()
和concat()
。
arr.some(() => {}):查找数组中有没有符合条件的数组
arr.concat(arr1, arr2, ...):将传入的数组拼接到前面的数组上
使用这个方法我们只需要一个思路:因为我们需要将里面的嵌套数组给扁平化成一维数组,那么我们只需要判断当前数组中的每一项,如果有item是Array,就使用concat()对其解构并且将其拼接到一个新的数组中,直到原数组中没有item是Array为止。下面我们来看完整代码:
js
let arr = [1, [2, [3, 4, [5]]]]
function flatten4(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr)
}
return arr
}
console.log(flatten4(arr));
递归
前面几种方法呢多多少少都离不开数组身上自带的方法,但是正所谓自己动手丰衣足食,咱也不能一直吃软饭,接下来我们来手搓一个扁平化。
思路:我们先定义一个结果数组res,接着我们对数组进行遍历,当发现item的类型是Array时,我们就对其进行递归并且对递归出来的结果进行解构拼接到我们的结果数组中即可,如果是原始类型就直接插入即可。
js
let arr = [1, [2, [3, 4, [5]]]]
function flatten2(arr) {
let res = []
for (let item of arr) {
if (Array.isArray(item)) {
res.push(...flatten2(item))
// res = [...res, ...flutter(item)]
// res = res.concat(flutter(item))
} else {
res.push(item)
}
}
return res
}
console.log(flatten4(arr));