概念: 数组扁平化就是数组内的嵌套数组展开放置在原位置 .
简单说一下个人对实现数组扁平化的三种方式以及使用场景
- Array.prototype.flat()
- 递归
- Array.prototype.reduce()
- 展开运算符
1. Array.prototype.flat()
使用场景: 知道层级最深的嵌套数组 .
举个例子说一下: 比如有一个数组, 数组中存在着不同层级的嵌套数组, 比如说第二项嵌套了两层数组, 第五项嵌套了五层数组, 此时使用 flat(5) 即可实现扁平化 .
const arr = [1, 2, [3, 2, 2, [11, 33]], [2, [2]], [[[666, 999, [100]]]]]
const res = arr.flat(4)
console.log(res); // [1, 2, 3, 2, 2, 11, 33, 2, 2, 666, 999, 100]
2. 递归
使用场景: 不知道层级最深的嵌套数组 .
主要思路 : 声明一个空数组, 遍历需要扁平化的数组, 如果该项不是数组就追加到空数组, 如果该项是数组就再次调用递归函数, 遍历该项, 以此类推就实现了扁平化.
const arr = [1, 2, [3, 2, 2, [11, 33]], [2, [2]], [[[666, 999, [100]]]]]
let res = []
function flat(arr) {
arr.forEach(item => {
if (item instanceof Array) {
flat(item)
} else {
res.push(item)
}
})
}
flat(arr)
console.log(res); // [1, 2, 3, 2, 2, 11, 33, 2, 2, 666, 999, 100]
// 简化一点
const arr = [1, 2, [3, 2, 2, [11, 33]], [2, [2]], [[[666, 999, [100]]]]]
let res = []
function flat(arr) {
arr.forEach(item => item instanceof Array ? flat(item) : res.push(item))
}
flat(arr)
console.log(res); // [1, 2, 3, 2, 2, 11, 33, 2, 2, 666, 999, 100]
3. Array.prototype.reduce()
reduce方法对数组中的每一项执行你所自定义的函数, 可以将想要的结果返回出去。
reduce的参数 :
- 提供的函数
- 初始值
自定义函数的参数 :
- Accumulator (acc) (累计器(就是你设置的初始值))
- Current Value (cur) (当前值)
- Current Index (idx) (当前索引)
- Source Array (src) (源数组)
具体的细节可以查看MDN文档 .
简单说以下函数做了什么 :
首先定义了一个flat函数和初始值[], 将数组传递了进去, 调用了数组的reduce()方法, 传入了自己定义的函数,函数内接受参数, 累计数组, 当前值, 函数内的逻辑就是判断当前值是不是数组, 如果不是数组的话, 就把当前值拼接到累计数组中, 如果当前值是数组就递归调用一下flat函数, 在函数内对当前值进行判断是不是数组, 是数组就在调用flat函数, 不是的话就拼接到当前项的累加数组中, 最终把累加数组返回回去, 再和最初的累加数组拼接到一起, 从而实现一个扁平化的效果, 大家可以先找个数组项少的比如说[1,[2],3]来练练手看看执行流程.
const arr = [1, 2, [3, 2, 2, [11, 33]], [2, [2]], [[[666, 999, [100]]]]]
function flat(arr) {
return arr.reduce(function(accumulator, current) {
return accumulator.concat(current instanceof Array ? flat(current) : current)
}, [])
}
const res = flat(arr)
console.log(res) // [1, 2, 3, 2, 2, 11, 33, 2, 2, 666, 999, 100]
简化后:
const arr = [1, 2, [3, 2, 2, [11, 33]], [2, [2]], [[[666, 999, [100]]]]]
function flat(arr) {
return arr.reduce((accumulator, current) => accumulator.concat(current instanceof Array ? flat(current) : current), [])
}
const res = flat(arr)
console.log(res) // [1, 2, 3, 2, 2, 11, 33, 2, 2, 666, 999, 100]
4. 展开运算符 + while语句
展开运算符可以展开数组, 使用while语句来进行循环展开
const arr = [1, 2, [3, 2, 2, [11, 33]], [2, [2]], [[[666, 999, [100]]]]]
function flat(arr) {
while (arr.some(item => item instanceof Array)) {
arr = [].concat(...arr)
}
return arr
}
console.log(flat(arr)); // [1, 2, 3, 2, 2, 11, 33, 2, 2, 666, 999, 100]