📕 重学JavaScript:多维数组如何“降维”?
嗨,大家好!这里是道长王jj
~ 🎩🧙♂️
你有没有遇到过这样的问题:你在前端项目开发中,可能会需要处理一些层叠数据结构的数组。层叠数据结构就像一个多层的蛋糕一样🍰
我们有一个多维数组,比如:
let ary = [1, [2, [3, [4, 5]]], 6];// -> [1, 2, 3, 4, 5, 6]
这个数组有四层,每一层都是一个数组。我们想要把这个数组变成一个一维数组,就是把所有的元素都放在一个数组里面。就像这样:
let ary = [1, 2, 3, 4, 5, 6];
这样我们就可以对新数组进行各种操作了,比如求和或排序。😊
但是,怎么才能把一个多维数组转换成一个一维数组呢?这可不是一件容易的事情!🤔
如果我们要遍历里面的数据,就需要执行两次for循环才能取出。那么除了这个方法,还有没有更好的方法使它能够让它展开呢?
方法一:调用ES6中的flat方法
这个方法可以直接实现我们的需求,把一个多维数组变成一个一维数组。我们只需要给它传入一个参数,表示要展开的层数。如果不确定有多少层,就传入Infinity,表示无限层。👗
let ary = [1, [2, [3, [4, 5]]], 6];
ary = arr.flat(Infinity);
console.log(ary); // [1, 2, 3, 4, 5, 6]
方法二:replace + split
如果我们没办法使用ES6的语法,我们只能从字符串的手段上下功夫了。
我们可以利用字符串的两个方法:replace和split。
replace可以把字符串中的某些字符替换成其他字符;
split可以把字符串按照某个字符分割成一个数组。
因此先将多维数组转换成一个字符串,然后用replace把所有的中括号去掉,再用split把每个逗号分割成一个元素来实现。
let ary = [1, [2, [3, [4, 5]]], 6];
let str = JSON.stringify(ary); // 把多维数组转换成字符串
ary = str.replace(/(\[|\])/g, '').split(',') // 去掉中括号,按逗号分割
console.log(ary); // ["1", "2", "3", "4", "5", "6"]
这样我们就实现了数组展开,不过注意一点,这个方法会把所有的元素都变成字符串,如果你想要数字,就需要再转换一下。😅
方法三:replace + JSON.parse
如果你并不想改变值类型该怎么办呢?
这个方法和上一个方法很类似,只不过它用了JSON.parse
来把字符串转换成数组。
JSON.parse可以把一个符合JSON格式的字符串转换成一个对象或者数组。
let ary = [1, [2, [3, [4, 5]]], 6];
let str = JSON.stringify(ary); // 把多维数组转换成字符串
str = str.replace(/(\[|\]))/g, ''); // 去掉中括号
str = '[' + str + ']'; // 在两边加上中括号
ary = JSON.parse(str); // 把字符串转换成数组
console.log(ary); // [1, 2, 3, 4, 5, 6]
这样我们就实现了数组展开,而且不会改变元素的类型。👍
方法四:递归
这个方法是比for循环遍历高级一点的,因为它利用了递归的思想。
递归就是让函数自己调用自己,直到满足某个条件为止。🚜
let ary = [1, [2, [3, [4, 5]]], 6];
let result = []; // 创建一个空数组
let fn = function(ary) {
// 定义一个递归函数
for(let i = 0; i < ary.length; i++) {
// 遍历每个元素
let item = ary[i];
if (Array.isArray(ary[i])){
// 如果是一个数组,就继续递归
fn(item);
} else {
// 如果不是一个数组,就放到空数组里面
result.push(item);
}
}
}
fn(ary); // 调用递归函数
console.log(result); // [1, 2, 3, 4, 5, 6]
这样我们就实现了数组展开,不过注意一点,这个方法会改变原来的数组,如果你不想改变原来的数组,就需要先复制一份。😅
方法五:利用reduce函数迭代
这个方法使用了 Javascript 的数组高级函数。
reduce函数可以对数组中的每个元素进行累计操作,返回一个最终的值。
function flatten(ary) {
// 定义一个展开函数
return ary.reduce((pre, cur) => {
// 对数组进行reduce操作
return pre.concat(Array.isArray(cur) ? flatten(cur) : cur); // 如果当前元素是一个数组,就递归调用展开函数;如果不是,就合并到新数组里面
}, []); // 初始值是一个空数组
}
let ary = [1, 2, [3, 4], [5, [6, 7]]]
console.log(flatten(ary)) // [1, 2, 3, 4, 5, 6, 7]
高级函数不会改变原来的数组和元素的类型。👍
方法六:...
扩展运算符
这个方法也是ES6新增的一个语法糖,它可以把一个多维数组变成一个一维数组。
我们只需要在多维数组前面加上三个点(…),就可以把它打散成多个元素。🎯
我们先看看...
扩展运算符有什么作用:
let ary = [[1, 2], [3, 4], [5, 6]];
console.log(...ary); // [1, 2] [3, 4] [5, 6]
这样我们就把多维数组打散了,但是还没有合并。
这个时候我们再将打散的元素合并即可,看看下面的例子:
let ary = [[1, 2], [3, 4], [5, 6]];
//只要有一个元素有数组,那么循环继续
while (ary.some(Array.isArray)) {
ary = [].concat(...ary); // 把多维数组打散和合并
}
console.log(ary); // [1, 2, 3, 4, 5, 6]
这样我们就实现了数组展开👏
方法七:常规for循环
当然,for循环当然是没有问题的,不过和以前的文章一样,这里我就不展开说明了😜
🎉 你觉得怎么样?这篇文章可以给你带来帮助吗?这是一个比较实用而且很容易被问到的问题,如果你有任何疑问或者想进一步讨论相关话题,请随时发表评论分享您的想法,让其他人从中受益。🚀✨