我正在参与掘金创作者训练营第4期,点击了解活动详情,一起学习吧!
我最近遇到一个问题二维数组转为一维数组?
我想到的是用for循环去循环每个项,判断该项是否是数组,如果是就在循环数组,然后存储到一个新的数组,如果不是,这直接存储到新的数组。
const arr = [1, 3, [4, 9], 8, 8, 9, [7, 0]];
const newArr = [];
for (let i = 0, max = arr.length; i < max; i++) {
if (Array.isArray(arr[i])) {
for(let j = 0, maxJ = arr[i].length; j < maxJ; j++) {
newArr.push(arr[i][j]);
}
} else {
newArr.push(arr[i]);
}
}
console.log(newArr)
运行结果
🥴 轻松解决!
这时候我又想,三维数组如何转为一维数组呢?
🤔 使用for循环到二维数组的时候再去判断是否是数组然后在存储,那四维数组的转为一维数组呢?那五维数组的转为一维数组呢? 难道要这样一层一层的循环下去? 事情好像没有那么简单,这个方法好像过于繁琐了,有没有简单一点的方法呢?
答案是有的。
apply加concat 解决二维数组降维
我们先来看二维数组降维简洁的方法
apply中的第一个参数为指定的this, 第二个参数是一个数组形式提供的参数,这样我们可以使用apply的第一个参数的this指向一个空数组,第二个参数是我们需要将维的数组,让数组成为一个个调用的参数。
const arr = [1, 3, [4, 9], 8, 8, 9, [7, 0]];
const newArr = Array.prototype.concat.apply([], arr);
console.log(newArr);
从以上的结果来看:使用apply加concat只需一句就能代替文章刚开头的两次for循环遍历二维数组降维数组的方法。
多维数组降一维
再来看上面的一张图,我们会发现apply加concat碰上三维数组也只能降一层,并不能实现多维数组降一维。
这还是没有实现我们想要的多维数组将维效果。
思考许久,决定试试使用递归函数来实现。
reduce() 是数组的归并方法,迭代数组所有项,并在此基础上构建一个最终返回值。
reduce() 有四个参数
- prev: 累计器
- cur: 当前值
- index: 当前索引
- array: 源数组
let values = [1, 2, 3, 4, 5];
let sum = values.reduce((prev, cur, index, array) => {
console.log(prev, cur);
return prev + cur;
})
console.log(sum);
从上图可以看出第一次执行时 prev 是 1, cur 是 2,第二次执行时prev 是 3 cur 是 3, 这里prev是3的原因是因为 1 + 2 = 3 所以prev是3,第三次执行的时候prev是6 (3 + 3), cur 是4,以此类推。最后sum 得出总和是15.
由此可以看出 prev 相当于是把之前执行的结果存放的起来的值。
所以我们可以使用reduce的累计器来存放一个新的一维数组,判断是否是数组,如果是数组就在调用该函数,实现一个递归函数。
const arr = [1, 3, [4, [3, 5, 10], 9], 8, 8, 9, [7, 0]];
const dropDimension = (oldArr) => {
const _newArr = oldArr.reduce((prev, cur) => {
if (Array.isArray(cur)) {
return prev.concat(...dropDimension(cur));
}
return prev.concat(cur);
}, []);
return _newArr;
}
const newArr = dropDimension(arr);
console.log(newArr);
这个方法是使用了递归函数来实现了多维数组转为一维数组。那么还有没有更简单的方法呢?当然是有的。今天的重头戏来了那就是flag 数组方法。
flat() 数组 ‘拉平’
flat()是ES6推出的新特性,用于将嵌套数组‘拉平’,变为一维数组。
那我们立马来试试这个方法吧。
const arr = [1, 3, [4, 9], 8, 8, 9, [7, 0]]
const newArr = arr.flat()
console.log(newArr)
使用flat()方法立马就能把二维数组转维一维数组了,那么让我们试试三维数组吧。
🙊怎么没有把三维数组转为一维数组呢?
原来 flat()方法还有一个参数
- depth 是数组的深度。代表需要‘拉平’几层的嵌套数组
像三维数组我们想拉平为一维数组就需要传入参数 2
四维数组如果参数为 2那么将只拉平两层
四维数组想要拉平为一维数组 参数就要传入 3,以此类推
那么如果我们不知道层数的嵌套数组想直接转为一维数组的话,我们可以传入参数Infinity的关键字,这样不管数组是几层嵌套都能直接转为一维数组了。
const arr = [1, 3, [4,[2, 6, [6, 7, 8], 8, 9], 9], 8, 8, 9, [7, 0]]
const newArr = arr.flat(Infinity)
console.log(newArr)
以上就是多维数组转为一维数组的几种方法了,我觉得最好用的就是flat()的方法了。你们还有其他的多维数组转为一维数组的方法可以在评论里留言哦。