5种数组扁平化方法,让面试官对你刮目相看

5种数组扁平化方法,让面试官对你刮目相看

前记

其实一开始想写这个专栏很久了,因为面试中的"魔鬼面试官"总会这么说:"数组扁平化知道吗,你知道多少种就写多少种",这个时候的我就开始抓耳挠腮了。这个专栏我想我会写一段时间,后续还会写到熟视无睹的浅拷贝和深拷贝、面试让你说出区别的防抖节流、神秘莫测的函数柯里化等等。

方法一:ES6 的 flat 方法

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

这是数组自带的扁平化方法,flat的参数是说明需要展开几层,如果是Infinity无穷大的话,就是不管嵌套了几层,全部都会被展开 。想必这是大家一开始就想到的方法,毕竟那么好用的方法谁会不喜欢,但是如果你只知道这个的话,那不开心的肯定是面试官了。

方法二:递归

递归 ,用官方的话讲就是:在数学和计算机科学中,是指在函数的定义中使用函数本身的方法。通俗的话讲就是 自己调用自己

js 复制代码
const arr = [1, [2, [3, [4, 5]]], 6];
const array = [];
const fn = (arr) => {
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      fn(arr[i]);
    } else {
      array.push(arr[i]);
    }
  }
};
fn(arr);
console.log(array);

最早接触使用扁平化递归的时候还是在刷蓝桥杯的题目,这应该也是面试中大家会写出来的方法,一整个全文背诵!

方法三:使用正则

js 复制代码
const arr = [1,[1,2],[1,[3]]];
const res = JSON.stringify(arr).replace(/\[|\]/g, "");
const res2 = JSON.parse("[" + res + "]");
console.log(res2);

使用正则是我当时躺在床上想着有没有那种很难想到却很容易实现的方法,而正则是其实是我一直比较容易忘记的点,就那天却刚好想到这个点子:

  • 首先是使用 JSON.stringify 把 arr 转为字符串
  • 接着使用正则把字符串里面的 [ 和 ] 去掉
  • 然后再拼接数组括号转为数组对象

方法四:使用 reduce

js 复制代码
const arr = [1,[1,2],[1,[3]]];
const newArr = (arr) => {
  return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? newArr(cur) : cur);
  }, []);
};
console.log(newArr(arr), "reduce方法");

reduce 想必都是大家很喜欢的一个数组api,因为它相比于其他api,可玩性真的好很多。这里也用reduce来实现一下数组扁平化,其中也使用了 concat用于连接两个或多个数组,且该方法不会更改现有数组,而是返回一个新数组,其中包含已连接数组的值。

方法五:使用栈的思想实现 flat 函数

栈(stack),官方解释:又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。

js 复制代码
function flat(arr) {
  const newArr = [];
  const stack = [].concat(arr); 
  while (stack.length !== 0) {
    const val = stack.pop();
    if (Array.isArray(val)) {
      stack.push(...val);
    } else {
      newArr.unshift(val);
    }
  }
  return newArr;
}

let arr = [1,[1,2],[1,[3]]];
console.log(flat(arr));

感觉用递归实现的需求用栈也能实现,就像树的三种遍历方式一样。实现的流程:

  • 将数组元素拷贝至栈,直接赋值会改变原数组
  • 如果栈不为空,则循环遍历
  • 删除数组最后一个元素,并获取它
  • 如果是数组再次入栈,并且展开了一层
  • 如果不是数组就将其取出来放入结果数组中

待续

相关推荐
馬致远8 分钟前
Vue TodoList 待办事项小案例(代码版)
前端·javascript·vue.js
Dream it possible!12 分钟前
LeetCode 面试经典 150_字典树_添加与搜索单词 - 数据结构设计(96_211_C++_中等)
c++·leetcode·面试·字典树
一字白首24 分钟前
Vue 进阶,Vuex 核心概念 + 项目打包发布配置全解析
前端·javascript·vue.js
想用offer打牌25 分钟前
一站式了解http1.1,http2.0和http3.0
后端·网络协议·面试
栀秋66627 分钟前
从前端送花说起:HTML敲击乐与JavaScript代理模式的浪漫邂逅
前端·javascript·css
jun_不见32 分钟前
面试官:你能说下订阅发布模式么,怎么在VUE项目中实现一个类似eventBus的事件总线呢
前端·javascript·面试
南山安33 分钟前
React学习:组件化思想
javascript·react.js·前端框架
不一样的少年_1 小时前
【用户行为监控】别只做工具人了!手把手带你写一个前端埋点统计 SDK
前端·javascript·监控
踏浪无痕1 小时前
基于Nacos的轻量任务调度方案 —— 从 XXL-Job 的痛点说起
后端·面试·架构
Glommer1 小时前
AST 反混淆处理示例(二)
javascript·爬虫