关于数组扁平化你能写出几种

493 阅读4分钟

前言

今天我们来看看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']

当然肯定也还有其他一些比较巧妙的方法也可以实现这个要求,其余的方法就不一一举例了,但是思路基本都是一致的,有兴趣可以自己研究一波~

好啦,关于数组扁平化的部分到这就差不多了,以后面试官让你手撸的时候我相信你应该也可以搞定啦~

文末

最后如果文章对你有用的话,欢迎点赞👍、关注😌,谢谢~