面试官:聊聊数组扁平化

前言

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

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));
相关推荐
浪遏17 分钟前
我的远程实习(六) | 一个demo讲清Auth.js国外平台登录鉴权👈|nextjs
前端·面试·next.js
朴拙数科1 小时前
技术长期主义:用本分思维重构JavaScript逆向知识体系(一)Babel、AST、ES6+、ES5、浏览器环境、Node.js环境的关系和处理流程
javascript·重构·es6
拉不动的猪2 小时前
vue与react的简单问答
前端·javascript·面试
牛马baby2 小时前
Java高频面试之并发编程-02
java·开发语言·面试
旭久3 小时前
react+antd封装一个可回车自定义option的select并且与某些内容相互禁用
前端·javascript·react.js
阿丽塔~3 小时前
React 函数组件间怎么进行通信?
前端·javascript·react.js
yuanbenshidiaos3 小时前
面试问题总结:qt工程师/c++工程师
c++·qt·面试
冴羽3 小时前
SvelteKit 最新中文文档教程(17)—— 仅服务端模块和快照
前端·javascript·svelte
uhakadotcom3 小时前
Langflow:打造AI应用的强大工具
前端·面试·github