数组扁平化是指将一个多维数组变成一维数组。如:
[1, [[2, 3], 4]] --> [1, 2, 3, 4]
Array.prototype.flat()
ES10 引入了 Array.prototype.flat()
方法,使扁平数组变的简单。
const arr = [1, [2, [3, [4, 5]]], 6]
// 你可以指定展开多少层
arr.flat(1) // [1, 2, [3, [4, 5]], 6]
arr.flat(2) // [1, 2, 3, [4, 5], 6]
// 使用 Infinity 作为参数,可以展开无限嵌套数组
arr.flat(Infinity) // [1, 2, 3, 4, 5, 6]
Array.prototype.toString() 和 Array.prototype.join()
如果数组的元素都是数字,那么我们可以考虑使用 Array.prototype.toString()
或 Array.prototype.join()
方法。
调用数组的 Array.prototype.toString()
方法,将数组转为字符串再用 String.prototype.split()
分割还原为数组
const flatten = arr => arr.toString().split(',').map(item => +item)
flatten(arr) // [1, 2, 3, 4, 5, 6]
Array.prototype.join()
也可以实现同样的效果:
const flatten = arr => arr.join(',').split(',').map(item => +item)
flatten(arr) // [1, 2, 3, 4, 5, 6]
递归
对于具有更深层嵌套的数组,可以使用递归。
使用 Array.prototype.reduce()
遍历数组的每一项,若值为数组则递归遍历,否则使用 Array.prototype.concat()
拼接。
const flatten = (arr) => {
return arr.reduce(
(acc, val) =>
Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val),
[],
)
}
flatten(arr) // [1, 2, 3, 4, 5, 6]
扩展运算符
使用 Array.prototype.concat()
配合扩展运算符(...
)展开一级嵌套数组
// 这仅适用于一级嵌套数组
[].concat(...arr) // [1, 2, [3, [4, 5]], 6]
// 较旧的浏览器解决方案
[].concat.apply([], arr) // [1, 2, [3, [4, 5]], 6]
在配合 while
循环,只要有一个元素有数组,那么循环继续
const flatten = (arr) => {
while (arr.some(Array.isArray)) {
arr = [].concat(...arr)
}
return arr
}
flatten(arr) // [1, 2, 3, 4, 5, 6]
序列化后正则
const str = `[${JSON.stringify(arr).replace(/(\[|\])/g, '')}]`
JSON.parse(str) // [1, 2, 3, 4, 5, 6]