前言
今天我们来看看JavaScript当中的数组部分相关内容,可以说是我们无论是在日常开发中还是面试当中,都碰到的十分频繁,今天我们就以“数组的扁平化处理”这个话题来看看有关数组的问题
前置
首先我们在开始之前我们应该要搞清楚几个问题,看看我们能回答多少出来:
- 什么是数组扁平化呢?
- 数组扁平化实现的方法你可以说出几种呢?
如果你对某个问题有着疑问,那可以尝试往下阅读,看是否可以找到你要的答案~
什么是数组扁平化
其实理解起来很简单,顾名思义,数组的扁平化就是“把数组拍平”,换成我们的语言来说,就是把一个嵌套多层的数组转换为只有一层的数组,虽然很容易理解,但是我们还是用一个简单的例子来表示一下:
var arr = ['one', ['two', ['three']]]
=======>数组扁平化之后
arr = ['one', 'two', 'three']
很容易理解,知道了数组扁平化的概念,接下来我们就要开始盘点各种实现数组扁平化的方法了~
数组扁平化方法盘点
1、普通递归实现
这个方法不用多说把,大家都知道,就是不断递归遍历,一直到不为数组为止,并且这个过程中将每一个数组拼接起来,形成一个一维数组,我们直接看代码:
// 1、普通递归
var arr = ['one', ['two', ['three']]]
function flatten(arr) {
let result = []
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]))
} else {
result.push(arr[i])
}
}
console.log(result)
return result
}
flatten(arr) // ['one', 'two', 'three']
这种方式直接递归直接简单粗暴,很容易理解~
2、数组的reduce方法
大家应该知道数组的reduce方法吧,这个也是数组的一个遍历方法,某些情况下非常好用,同样也能用到我们这个地方,相对于来说代码会简洁一些:
我们也来看看代码:
// 2、reduce
function flatten2(arr) {
return arr.reduce((preValue, value) => {
return preValue.concat(Array.isArray(value) ? flatten2(value) : value)
}, [])
}
console.log(flatten2(arr)) // ['one', 'two', 'three']
3、扩展运算符实现
其实这种方法也很好理解,本质还是递归,只是我们是通过先过滤出还是数组的项,然后使用concat将扩展运算符展开之后的结果拼接起来就行了,我们直接看代码:
// ...
function flatten3(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
console.log(flatten3(arr)); // ['one', 'two', 'three']
我们不难发现,前面的本质思路都是利用递归来实现的,只不过是组合不同的方法来简化代码,接下来我们需要来看看不同的实现思路
4、利用字符串的方式
我们知道数组也有一个toString方法,这个方法可以直接把数组转成一个字符串,这时候我们直接使用字符串转数组的方法就行了,我们看代码:
// 字符串的方式
function flatten4(arr) {
return arr.toString().split(',')
}
console.log(flatten4(arr)) // ['one', 'two', 'three']
是不是很简单,是不是很神奇~
5、特定的数组扁平化方法flat
接下来我们就来看看直接调用数组扁平化方法flat,这个我们可能用到的不是太多,我们先来看看他的语法:
var newArray = arr.flat([depth])
我们可以看到flat需要传递一个参数depth(这个参数表示需要展开数组的深度,如不填则默认为1层),所以如果需要展开几层就传入相应数字即可,所以如果是多层展开的话,我们直接传入Infinity(无穷大的意思),代表着无论多少层都要展开
我们来看下实现代码:
// 特定的数组扁平化方法flat
function flatten5(arr) {
return arr.flat(Infinity);
}
console.log(flatten5(arr)); // ['one', 'two', 'three']
我们看完了这个方法,是不是会好奇这个方法的底层是怎么实现的,接下来我们就来看一下这个方法的简单实现代码:
// flat实现
function flat(arr, depth) {
let res = []
let depthArg = depth || 1
let depthNum = 0,
flatMap = (arr) => {
arr.map((element, index, array) => {
// 判断是否是数组类型(之前文章有写过)
if(Object.prototype.toString.call(element).slice(8, -1) === 'Array'){
if(depthNum < depthArg){
depthNum++;
flatMap(element);
}else{
res.push(element);
}
}else{
res.push(element);
if(index === array.length -1) depthNum = 0;
}
});
};
flatMap(arr);
return res;
}
console.log(flat(arr, Infinity)) // ['one', 'two', 'three']
当然肯定也还有其他一些比较巧妙的方法也可以实现这个要求,其余的方法就不一一举例了,但是思路基本都是一致的,有兴趣可以自己研究一波~
好啦,关于数组扁平化的部分到这就差不多了,以后面试官让你手撸的时候我相信你应该也可以搞定啦~
文末
最后如果文章对你有用的话,欢迎点赞👍、关注😌,谢谢~