前言
什么是扁平化数组?扁平化,顾名思义就是减少复杂性装饰,使其事物本身更简洁、简单,突出主题。 数组扁平化,对着上面意思套也知道了,就是将一个复杂的嵌套多层的数组,一层一层的转化为层级较少或者只有一层的数组
扁平化数组的n种方法
1. flat
利用ES6的flat方法:
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
const arr1 = [0, 1, 2, [3, 4]]
console.log(arr1.flat()) // [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2)) // [0, 1, 2, [3, 4]]
//使用 Infinity,可展开任意深度的嵌套数组
var arr3 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr3.flat(Infinity) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// flat()函数会自动清除列表中为空的元素
var arr4 = [1, 2, , 4, 5];
arr4.flat(); // [1,2,3,4]
2. reduce + concat
var arr = [1, 2, [3, 4]];
// 展开一层数组
arr.reduce((acc, val) => acc.concat(val), []) // [1, 2, 3, 4]
3. reduce + spread
使用扩展运算符
var arr = [1, 2, [3, 4]];
// 展开一层数组
const flattened = arr => [].concat(...arr)
console.log(flattened(arr)) // [1,2,3,4]
4. reduce + concat + isArray + recursivity
// 使用 reduce、concat 和递归展开无限多层嵌套的数组
var arr1 = [1, 2, 3, [1, 2, 3, 4, [2, 3, 4]]];
function flatDeep(arr, d = 1) {
if (d > 0) {
return arr.reduce((acc, val) => {
return acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val)
}, [])
} else {
return arr.slice()
}
};
flatDeep(arr1, Infinity); // [...]
5. forEach+isArray+push+recursivity
// forEach 遍历数组会自动跳过空元素
const eachFlat = (arr = [], depth = 1) => {
const result = []; // 缓存递归结果
// 开始递归
(function flat(arr, depth) {
// forEach 会自动去除数组空位
arr.forEach((item) => {
// 控制递归深度
if (Array.isArray(item) && depth > 0) {
// 递归数组
flat(item, depth - 1)
} else {
// 缓存元素
result.push(item)
}
})
})(arr, depth)
// 返回递归结果
return result;
}
var arr = [1, 2, [3, 4, [5, 6]]]
const flattened = eachFlat(arr) // [1, 2, 3, 4, [5, 6]]
const flattened2 = eachFlat(arr, Infinity) // [1, 2, 3, 4, 5, 6]
6. 使用堆栈 stack
// 无递归数组扁平化,使用堆栈
// 注意:深度的控制比较低效,因为需要检查每一个值的深度
// 也可能在 shift / unshift 上进行 w/o 反转,但是末端的数组 OPs 更快
var arr1 = [1, 2, 3, [1, 2, 3, 4, [2, 3, 4]]];
function flatten(input) {
const stack = [...input];
const res = [];
while (stack.length) {
// 使用 pop 从 stack 中取出并移除值
const next = stack.pop();
if (Array.isArray(next)) {
// 使用 push 送回内层数组中的元素,不会改动原始输入
stack.push(...next);
} else {
res.push(next);
}
}
// 反转恢复原数组的顺序
return res.reverse();
}
flatten(arr1); // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
7. 使用迭代器
function* flatten(array) {
for (const item of array) {
if (Array.isArray(item)) {
yield* flatten(item);
} else {
yield item;
}
}
}
var arr = [1, 2, [3, 4, [5, 6]]]
const flattened = [...flatten(arr)] // [1, 2, 3, 4, 5, 6]
8. join+split
function flat(arr) {
return arr.join().split(',').map(item => parseInt(item))
}
var arr = [1, 2, [3, 4, [5, 6]]]
const flattened = flat(arr) // [1, 2, 3, 4, 5, 6]
9. toString+split
function flat(arr) {
return arr.toString().split(',').map(item => parseInt(item))
}
var arr = [1, 2, [3, 4, [5, 6]]]
const flattened = flat(arr) // [1, 2, 3, 4, 5, 6]