面试官:聊聊数组扁平化

前言

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

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));
相关推荐
软件开发技术深度爱好者1 小时前
小学英语单词魔法学园HTML5实现
javascript·html5·英语学习
勉灬之1 小时前
Next.js + Prisma 跨平台部署踩坑记
开发语言·javascript·ecmascript
糖果店的幽灵1 小时前
langgraph分支之 - 动态分支(Dynamic Branch)
java·前端·javascript·人工智能·langgraph
我叫黑大帅1 小时前
我为什么单一消费者的场景下,要用 Redis List 当消息队列?
redis·后端·面试
吃饱了得干活2 小时前
亿级订单表分库分表设计,从0到1全流程
java·数据库·面试
这是个栗子2 小时前
前端开发中的常用工具函数(九)
开发语言·javascript·ecmascript·at
Revolution613 小时前
一段 JavaScript 代码执行时,到底发生了什么
前端·javascript
程序员爱钓鱼5 小时前
Go 开发环境安装(Windows、macOS、Linux)
后端·面试·go
触底反弹5 小时前
🤯 面试被问 AI Workflow 和 Agent 有啥区别?3 张图 + 2 段代码讲清楚!
人工智能·设计模式·面试
uzong12 小时前
一个好的面试官,应该让候选人感到被尊重
面试