面试官:实现一个 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
}

写在最后

感谢彦祖们的阅读

个人能力有限

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

相关推荐
zhougl9962 小时前
html处理Base文件流
linux·前端·html
花花鱼2 小时前
node-modules-inspector 可视化node_modules
前端·javascript·vue.js
HBR666_2 小时前
marked库(高效将 Markdown 转换为 HTML 的利器)
前端·markdown
careybobo3 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)4 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之5 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端5 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡5 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木6 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!6 小时前
优选算法系列(5.位运算)
java·前端·c++·算法