JavaScript 实现数组的扁平化处理

什么是数组的扁平化处理

数组的扁平化处理指将一个多维数组变成一维数组

1
[1, [2, 3, [4, 5]]] ---> [ 1, 2, 3, 4, 5 ]

Mode One (方式一) ES6flat()

ES6 提供了数组方法 flat(depth) 对数组进行扁平化处理。

参数:

  • depth 被扁平化的数组的层级,默认值为 1 可以为 Infinity ,表示完全扁平化
    返回值:
  • 一个扁平化处理后的新数组
1
2
3
4
const arr = [1, [2, 3, [4, 5]]]

const newArr = arr.flat(Infinity)
console.log(newArr) // [ 1, 2, 3, 4, 5 ]

Mode Two (方式二) ES6 的 拓展运算符

...[] 能用于拓展数组,将一个数组转为用逗号分隔的参数序列。

思想: 通过arr.some()判断数组是否还嵌套数组,嵌套就对嵌套在最外层的数组进行拓展运算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const arr = [1, [2, 3, [4, 5]]]

/**
* 拓展运算符扁平化处理
* @param {*} arr 可展开的数组结构
* @returns 展开后的数组
*/
function flatDeep(arr){
while(arr.some(item => Array.isArray(item))){
arr = [].concat(...arr)
}
return arr
}

console.log(flatDeep(arr)) // [ 1, 2, 3, 4, 5 ]

Mode Three (方式三) Array.reduce() 进行拓展

Array.reduce(pre, next) 能够对数组进行累计处理

参数:

  • pre 方法的前一个返回结果
  • next 当前数组元素
1
2
3
4
5
6
7
8
9
10
11
const arr = [1, [2, 3, [4, 5]]]
/**
* 使用 reduce() 方法进行扁平化处理
* @param {Array} arr 数组对象
* @returns
*/
function reduceFlatDeep(arr) {
return arr.reduce((pre, next) => pre.concat(Array.isArray(next) ? reduceFlatDeep(next) : next), []) // Array.isArray(next) ? pre.concat(reduceFlatDeep(next)) : pre.concat(next)
}

console.log(reduceFlatDeep(arr)) // [ 1, 2, 3, 4, 5 ]

Mode Four (方式四) 递归实现

思想: 对每一层的每一个数组进行处理,使其变成一维数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const arr = [1, [2, 3, [4, 5]]]
/**
* 使用递归进行数组扁平化
* @param {Array} arr 数组
* @returns
*/
function diGuiFlat(arr){
let res = []
for (const item of arr) {
if (Array.isArray(item)) {
res = res.concat(diGuiFlat(item))
}else {
res.push(item)
}
}
return res
}

console.log(diGuiFlat(arr)) // [ 1, 2, 3, 4, 5 ]

Mode five (方式五) toStirng() 和 split()

toString() 能够将数组转为以 , 分割的字符串.

splt(flag) 能够将字符串以 flag 进行分割

参数:

  • flag 指定的字符串分割字符

思想: 先通过 toString() 方法将数组转为字符串,再通过 split() 方法将字符串转为数组,再通过 map() 函数改变转变后的数据类型

1
2
3
4
5
6
7
8
9
10
const arr = [1, [2, 3, [4, 5]]]
/**
* toStirng() 和 split() 扁平化处理数组
* @param {Array} arr 嵌套数组
* @returns
*/
function toStringAndSplitFLat(arr) {
return arr.toString().split(',').map(Number)
}
console.log(toStringAndSplitFLat(arr)) // [ 1, 2, 3, 4, 5 ]

注意:这个方法会改变原数据的数据类型,谨慎使用

Mode Six (方式六) join() 和 split()

join(flag) 方法能够以 flag 连接数组元素

参数:

  • flag 指定的字符串连接字符
1
2
3
4
5
6
7
8
9
10
11
const arr = [1, [2, 3, [4, 5]]]
/**
*
* @param {Array} arr 嵌套数组
* @returns
*/
function joinAndSpltFlat(arr) {
return arr.join(',').split(',').map(Number)
}

console.log(joinAndSpltFlat(arr)) // [ 1, 2, 3, 4, 5 ]