持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
数组扁平化在我们日常生活中还是十分常见的,比如后台返回我们的数组中还包含二维数组,而我们又需要它是一维数组,这时候就需要将这个多维数组展开了。
数组扁平化的方法很多,下面我们就来一起看看它有哪些方法吧!
flat
ES6的数组新增了一个API,专门用于数组的扁平化,这也是我日常中使用最多的方法。它有一个可选参数,这个参数的作用是将数组扁平化几层,如果不传参就默认为1。
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.flat()) // [1, 2, 3, 4, 5, 6, [7, 8], 9, 0]
我们发现它只是展开了一层,如果要全展开就需要传递参数2:
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.flat(2)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
但是有时候我们不知道层数怎么办?那就可以传递Infinity作为参数,它的作用就是将它扁平化为1维数组:
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.flat(Infinity)) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
toString与split
数组重写了toString方法,它的toString不再是返回类型,而是返回数组的所有数值的字符串,并以逗号分隔。
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.toString()) // 1,2,3,4,5,6,7,8,9,0
然后我们再使用split将字符串转为数组就可以了。
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(a.toString().split(',')) // ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
不过它有一个缺点,就是会改变这个数值的类型,将它转为了string类型了。如果数组中包含对象类型或者函数的话,这个方法就得pass,因为它会将对象转为[object Object],将函数转为字符串.
let aa = function(){}
let a = [1,2,[3,true],{a:1},[6,[7,aa],9],0];
console.log(a.toString().split(','))
递归
我们也可以使用老办法———递归的方式进行数组的扁平化:
原理就是使用concat的方式进行拼接。
function myFlatten(arrays) {
let arr = [];
arrays.forEach((item, index) => {
if (Array.isArray(item)) {
arr = arr.concat(myFlatten(item));
} else {
arr.push(item)
}
})
return arr;
}
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(myFlatten(a)); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
我们发现这会开辟很多空间,会声明很多的arr。
reduce改进
function myFlatten(arrays) {
return arrays.reduce((arr,now)=>{
if(Array.isArray(now)) {
arr = arr.concat(myFlatten(now))
} else {
arr.push(now)
}
return arr
},[])
}
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(myFlatten(a)); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
扩展运算符
我们也可以使用ES6新增的扩展运算符来进行数组的扁平化。扩展运算符的作用就是将可迭代对象展开。
let a = [1,2,3,[4,[5,6,[7]]]];
console.log(...a); // 1,2,3,[4,[5,6,[7]]]
let str = 'aaaaa';
console.log(...str) // a a a a a
let set = new Set([1,2,3])
console.log(...set) // 1 2 3
...
所以它是不是有一点像flat(1)呢?
function myFlatten(arrays) {
while(arrays.some((item)=>Array.isArray(item))) {
arrays = [].concat(...arrays); // 循环了两次
}
return arrays;
}
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(myFlatten(a)); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
正则
最后一种使用方式就是正则了,先使用JSON.stringify()对其进行序列化,然后使用正则去掉所有的 '[' 和 ']' ,最后再在外面包裹一层就可以了。
function myFlatten6(arrays) {
let str = JSON.stringify(arrays);
str = str.replace(/([|])/g,'')
str = `[${str}]`;
return str;
}
let a = [1,2,[3,4],5,[6,[7,8],9],0];
console.log(myFlatten6(a)); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]