js 数组扁平化, 多方法实现
// 全局变量 arr
const arr = [1, [2, [3, [4, 5]]], 6, 7, [8, 9]]
方法一 使用 Array.prototype.flat()
/**
* 使用 Array.prototype.flat()
* flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
*
* var newArr = arr.flat([depth])、
*
* 参数 depth 可选
* 指定要提取嵌套数组的结构深度,默认值为 1。
*
* 返回值
* 一个包含将数组与子数组中所有元素的新数组。
*
*/
const res1 = arr.flat(Infinity)
console.log(res1) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
方法二 使用 正则
/**
* 使用 正则
* 先使用JSON.stringify(arr)将数组转换为json字符串,在使用字符串方法 .replace(参数1:正则表达式 /\[|\]/g, 参数二: '' 替换为空字符串 ) 在使用字符串的 split(参数1: ',' 以逗号为分割符)方法,
*
* 弊端
* 数据类型都会变为字符串
*
*/
const res2 = JSON.stringify(arr).replace(/\[|\]/g, '').split(',')
console.log(res2) // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
方法三 使用 升级版正则
/**
* 使用 升级版正则
* 使用 JSON.parse() 解析JSON.stringify(arr).splace(/\[|\]/g, '')的字符串结果在前后分别加上 字符窜 '['']'
* JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']') 这样方法二的 弊端就不存在了
*
*/
const res3 = JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']')
console.log(res3) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
方法四 使用 Array.prototype.reduce()
/**
* 使用 Array.prototype.reduce()
* reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
*
* 函数参数
*
* callback
* Accumulator (acc) (累计器)
* Current Value (cur) (当前值)
* Current Index (idx) (当前索引)
* Source Array (src) (源数组)
* 您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
*
* initialValue 可选
* 作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
*
* 使用reduce方法, 在callback函数体内,用参数1 累加器(累加器的初始值为 []空数组),然后使用数组 concat()合并方法,concat的参数 使用Array.isArray() 判断当前值是否为数组,返回值为 true | false, 返回值为 true 再次调用 flatten(参数是当前值 cur) 返回值为 false 直接合并数组
*
*/
const flatten = (data) => {
return data.reduce((acc, cur) => {
return acc.concat(Array.isArray(cur) ? flatten(cur) : cur)
}, [])
}
const res4 = flatten(arr)
console.log(res4) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
方法五 使用 递归函数
/**
* 使用 递归函数
*
* 解析
* flatten2(arr) 函数体内,使用for循环遍历参数 arr,循环体内 用Array.isArray(data[i]) 是否为数组,返回值true,继续递归调用 flatten2(data[i]), 返回值false, res5.push(data[i]), 知道循环完毕
*
*/
const res5 = []
const flatten2 = (data) => {
for (let i = 0; i < data.length; i++) {
if (Array.isArray(data[i])) {
flatten2(data[i])
} else {
res5.push(data[i])
}
}
}
flatten2(arr)
console.log(res5) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]