面试官:聊聊数组扁平化

前言

在聊这个问题之前,我们先得理解什么是扁平化?其实扁平化就是字面意思,当我们的数组中嵌套了很多的数组时,我们将其变成一维数组的方法,这就是扁平化,接下来我们来聊聊几种扁平化的方法。

arr.flat()

我们都知道数组身上有许多自带的方法,比如map,filter等遍历方法,除了这些方法之外,它身上还自带了一个可以扁平化数组的方法flat(),它的里面可以传递一个参数,想要将数组扁平几维度就传入几,下面我们来看个例子:

js 复制代码
let arr = [1, [2, [3, 4]]]
console.log(arr.flat(1));
console.log(arr.flat(2));

// 输出:
[ 1, 2, [ 3, 4 ] ]
[ 1, 2, 3, 4 ]

这时候就有一个问题了,如果我们不确定数组中嵌套了几层,那么如何将其扁平化为一维数组呢?我们都知道里面传入的数字就代表扁平化几次,那么我们一直扁平下去直到扁平成一维就能解决这个问题,这时候我们直接传入Infinity

js 复制代码
let arr = [1, [2, [3, 4, [5]]]]
console.log(arr.flat(Infinity));

// 输出:
[ 1, 2, 3, 4, 5 ]

toString()

我们都知道在js中每个类型都有自己的一个toString()方法,数组身上的toString()方法可以直接将数组中的元素都变成字符串并且以逗号拼接起来,除了这个效果之外,它还能实现一个扁平化的效果,我们来看一个示例:

js 复制代码
let arr = [1, [2, [3, 4, [5]]]]
console.log(arr.toString());

// 输出:
// 1,2,3,4,5

这时候我们只需要再使用split()方法将字符串转化为数组即可。

js 复制代码
let arr = [1, [2, [3, 4, [5]]]]

function flatten3(arr) {
  return arr.toString().split(',').map(item => +item)
} 

tips:这个方法是个取巧的方法,只能处理里面是原始类型的数组

some() + concat()

在介绍这个方法之前,我们先来了解一下数组身上自带的两个方法some()concat()

arr.some(() => {}):查找数组中有没有符合条件的数组

arr.concat(arr1, arr2, ...):将传入的数组拼接到前面的数组上

使用这个方法我们只需要一个思路:因为我们需要将里面的嵌套数组给扁平化成一维数组,那么我们只需要判断当前数组中的每一项,如果有item是Array,就使用concat()对其解构并且将其拼接到一个新的数组中,直到原数组中没有item是Array为止。下面我们来看完整代码:

js 复制代码
let arr = [1, [2, [3, 4, [5]]]]
function flatten4(arr) {
  while (arr.some(item => Array.isArray(item))) {
    arr = [].concat(...arr)
  }
  return arr
}

console.log(flatten4(arr));

递归

前面几种方法呢多多少少都离不开数组身上自带的方法,但是正所谓自己动手丰衣足食,咱也不能一直吃软饭,接下来我们来手搓一个扁平化。

思路:我们先定义一个结果数组res,接着我们对数组进行遍历,当发现item的类型是Array时,我们就对其进行递归并且对递归出来的结果进行解构拼接到我们的结果数组中即可,如果是原始类型就直接插入即可。

js 复制代码
let arr = [1, [2, [3, 4, [5]]]]

function flatten2(arr) {
  let res = []
  for (let item of arr) {
    if (Array.isArray(item)) {
      res.push(...flatten2(item))
      // res = [...res, ...flutter(item)]
      // res = res.concat(flutter(item))
    } else {
      res.push(item)
    }
  }
  return res
}

console.log(flatten4(arr));
相关推荐
Jiaberrr7 分钟前
uniapp Vue2 获取电量的独家方法:绕过官方插件限制
前端·javascript·uni-app·plus·电量
sss191s27 分钟前
校招 java 面试基础题目及解析
java·开发语言·面试
异常君30 分钟前
MySQL 中 count(*)、count(1)、count(字段)性能对比:一次彻底搞清楚
java·mysql·面试
Joker`s smile43 分钟前
使用React+ant Table 实现 表格无限循环滚动播放
前端·javascript·react.js
然我1 小时前
从原生 JS 到 React:手把手带你开启 React 业务开发之旅
javascript·react.js·前端框架
wkj0011 小时前
QuaggaJS 配置参数详解
java·linux·服务器·javascript·quaggajs
_一条咸鱼_1 小时前
Android Runtime链接(Linking)阶段准备工作(27)
android·面试·android jetpack
阿琳a_1 小时前
前端对WebSocket进行封装,并建立心跳监测
前端·javascript·vue.js·websocket
Am1nnn1 小时前
【Pinia】Pinia和Vuex对比
前端·javascript·vue.js
可爱小仙子1 小时前
ios苹果系统,js 滑动屏幕、锚定无效
前端·javascript·ios