面试官:实现一个 findIndexs?

前言

本文是笔者在业务开发中的一点函数封装技巧的分享总结

如果要用于实际项目,可能需要彦祖们自行改装

注: 本文重在设计思想的分享

在中高级前端面试中,经常会遇到这样的面试题

请你实现一个 call apply bind...

此时有位面试官让你实现一个 findIndexs 可以返回 [index,index1....]

那么我们该如何应对呢?

场景

彦祖们,今天遇到一个业务场景,要根据业务设置 echarts 的饼图颜色

业务上有四种状态,分别是

正常:green,异常:red,未知:gray,警告:yellow

后端返回的数据结构如下

js 复制代码
const data = [{value:335, name:'正常'},{value:310, name:'异常'},{value:234, name:'未知'},{value:135, name:'警告'}]

对应的 colorList 就是 ['green','red','gray','yellow']

但是后端返回的 data 顺序和个数 是不固定的

可能是

js 复制代码
[{value:335, name:'正常'}]

也可能是

js 复制代码
[{value:310, name:'异常'},{value:234, name:'未知'}]

那么我们就要找到对应的颜色,这个时候就可以用到数组的 findIndex 方法了

常规写法

笔者刚开始的写法是这样的

js 复制代码
const normalIndex = data.findIndex(item=>item.name === '正常')
const errorIndex = data.findIndex(item=>item.name === '异常')
const unknownIndex = data.findIndex(item=>item.name === '未知')
const warningIndex = data.findIndex(item=>item.name === '警告')
colorList[normalIndex] = 'green'
colorList[errorIndex] = 'red'
colorList[unknownIndex] = 'gray'
colorList[warningIndex] = 'yellow'

防御式编程正式开启😅

开始封装

既然我们已经看出来重复调用的次数有点多了

那么能不能把它封装成一个方法,那么就暂时就命名为 findIndexs

我们把它设计成传入多个函数,返回一个数组的形式

函数签名

看下大致的函数签名

js 复制代码
Array.prototype.findIndexs = function(fn1,fn2,fn2):[index1,index2,index3]

基础版 findIndexs

这里我们默认彦祖们已经对 js 的原型链有了一定的了解

有了大致思路,我们就简单来实现一下

js 复制代码
Array.prototype.findIndexs = function(...fns) {
  const arr = this // 这里要清楚 this 指向的就是调用的数组
  // 首先我们判断一下异常情况
  if(!Array.isArray(arr) || arr.length === 0) return []
  // 当然严谨一点的话,我们还可以判断一下 fns 里面的每个元素是否是函数
  return fns.map(fn=>arr.findIndex(fn)) // 这里我们用 map 来遍历 fns,然后调用 findIndex 方法,返回一个数组
}

那么最简单的一个 findIndexs 就实现了

我们来测试一下

js 复制代码
const [normalIndex,errorIndex,unknownIndex,warningIndex] = data.findIndexs(item=>item.name === '正常',item=>item.name === '异常',item=>item.name === '未知',item=>item.name === '警告')

这样我们就可以一行代码搞定了😊

双指针模式

当然我们还可以继续进行优化

针对这种有头有尾的遍历,我们可以采用双指针模式来提升遍历效率

js 复制代码
Array.prototype.findIndexs = function(...fns) {
  const arr = this
  if(!Array.isArray(arr) || arr.length === 0) return []
  // 如果再严谨点 就判断一下fns里面的每个元素是否是函数
  let count = fns.length,res=[]
  for(let i = 0,j=count-1;i<=j;i++,j--){
    if(i===j) res[i] = arr.findIndex(fns[i]) // 奇数长度 中位数只执行一次
    else{
      res[i] = arr.findIndex(fns[i])
      res[j] = arr.findIndex(fns[j])
    }
  }
  return res
}

写在最后

感谢彦祖们的阅读

个人能力有限

如有不对,欢迎指正 🌟 如有帮助,建议小心心大拇指三连🌟

相关推荐
TT模板10 分钟前
苹果cms整合西瓜播放器XGplayer插件支持跳过片头尾
前端·html5
Wect1 小时前
React 性能优化精讲
前端·react.js·性能优化
Cosolar1 小时前
告别无脑循环:深入解析 ReWOO 与 Plan-and-Execute Agent 架构
人工智能·面试·全栈
追风筝的人er1 小时前
SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解
前端·vue.js·后端
无敌的黑星星2 小时前
Java8 CompletableFuture 实战指南
linux·前端·python
雁鸣零落2 小时前
如何在 Chrome 中查看其他浏览器的书签?书签空间订阅与侧边栏只读切换指南
前端·chrome·edge浏览器
Fuly10242 小时前
技术经理面试相关--技术篇
面试·职场和发展
hpoenixf2 小时前
一天上线 + 零返工:我如何给复杂前端需求建立“安全感”
前端
逻辑驱动的ken3 小时前
Java高频面试考点18
java·开发语言·数据库·算法·面试·职场和发展·哈希算法
广州华水科技3 小时前
单北斗GNSS变形监测系统在水利工程安全保障中的应用与优势分析
前端