面试官在“逗”你系列:数组去重你会几种呀?
前言
数组去重是一个老生常谈的话题,也是前端童鞋在面试时的一道高频题。本文将深入的探索数组去重的原理及实现,为各位小伙伴提供多种
可以反手“调戏”
面试官的解决方案。
话不多说,上去就来一梭子...
数组去重核心原理
价值100W的核心原理上来就给你了...,记得留言点赞鸭!
- 一般我们都会创建临时变量tmp,存储不重复的元素(以数组元素存储或对象的键来存储);
- 遍历待去重数组arr,依次判断tmp中是否包含该元素;
- 若tmp中不存在该元素,则放入;否则跳过不处理。
基本上无论什么样的实现,其核心皆是如此(判断是否已存在)。不行你就留言,咱们可以
battle
一下
经典去重方案一:
设置tmp为对象,对象的键存储数组元素的值,最终返回对象的所有键。
function array_unique (arr) { if (arr.length === 0) { return arr } let tmp = {} let len = arr.length for (let i = 0; i < len; i++) { if (tmp[arr[i]] === undefined) { tmp[arr[i]] = i } } return Object.keys(tmp) } // 调用数组去重 let arr = [1, 2, 3, 1, 2] let newArr = array_unique(arr) console.log(newArr) // ['1', '2', '3']
如果你采用这种方式来回答面试官的话,你就陷入了他在内心中早早设下的陷阱:
你这种方式能区分数字和字符串吗?能区分
undefined
和'undefined'
吗?你现在返回的数据类型还和原有的数据类型一致吗?
带着面试官的疑问,我们来看另外一种经典去重方式。
经典去重方式二:
设置tmp为数组,数组中存储唯一的元素,最终返回tmp
function array_unique (arr) { let len = arr.length if (!len) { return [] } let tmp = [] for (let i = 0; i < len; i++) { // 判断数组arr的元素是否在数组tmp中 if (tmp.indexOf(arr[i]) === -1) { tmp.push(arr[i]) } } return tmp } let arr = [1, 2, 3, '1', 2, undefined, undefined, 'undefined'] let newArr = array_unique(arr) console.log(newArr) // [1, 2, 3, '1', undefined, 'undefined']
此刻,内心是否窃喜!
But, 如果你这么考虑,又陷入了面试官的另一个陷阱:
- 你这方式能筛选NaN吗?
好吧,面试官最大,再考虑!
数组去重方式三:
原理还是同去重方式二,只不过我们使用ES6的
includes
替换indexOf
方法,includes() 方法,判断数组中是否包含某个元素,如果包含返回true,否则返回false
就是这么so easy!
function array_unique (arr) { let len = arr.length if (!len) { return [] } let tmp = [] for (let i = 0; i < len; i++) { // 判断数组arr的元素是否在数组tmp中 if (!tmp.includes(arr[i]) { tmp.push(arr[i]) } } return tmp } let arr = [1, 2, 3, '1', 2, undefined, undefined, 'undefined', NaN, NaN] let newArr = array_unique(arr) console.log(newArr) // [1, 2, 3, '1', undefined, 'undefined', NaN]
此刻,你以为就结束吗?不,不可能!
面试官的坑已经在前面等你很久了:
- 你的这个筛选方式能区分对象吗?如{}、{a: 1}
有没有想把自己的四十米大砍刀拿出来,neng屎
面试官!(图就不配了,自己脑补吧...) 然而,什么都做不了,继续想吧...
数组去重方式四:
原理同上,我们要继续换一个判断数组是否包含某元素的方法:```findIndex``
findIndex
查询数组是否包含某元素,如果存在返回元素的索引,否则返回-1。它比indexOf更加先进的地方在于能传入callback
,按约定方式查询。
function array_unique (arr) { let len = arr.length if (!len) { return [] } let tmp = [] for (let i = 0; i < len; i++) { // 判断数组arr的元素是否在数组tmp中 if (tmp.findIndex((v) => JSON.stringify(v) === JSON.stringify(arr[i])) === -1) { tmp.push(arr[i]) } } return tmp } let arr = [1, 2, 3, '1', 2, undefined, undefined, 'undefined', NaN, NaN, {}, {}, {a: 1}, {a: 1}] let newArr = array_unique(arr) console.log(newArr) // [1, 2, 3, '1', undefined, 'undefined', NaN, {}, {a: 1}]
终于成功啦!来来来,可以潇洒的问面试官,“您还有问题没有?”
当然,主动挑衅面试官,是要承担风险呦,有可能会因为你眨眼的时候,先眨了右眼被挂掉了...
判断数组是否包含某元素的几种方式:
给大家列个表格,好区分几个方法的作用,
方法\是否可检测 | null | undefined | NaN | {} | 备注 |
---|---|---|---|---|---|
indexOf | 是 | 是 | 否 | 否 | 无 |
includes | 是 | 是 | 是 | 否 | 无 |
findIndex | 是 | 是 | 是 | 是 | 需传入特定的callback |
小结
数组去重这道面试题,考察的知识点还是非常多的。首先是对数组的常用方法要比较熟悉,还有其他的如NaN与NaN不相等,{}与{}不相等等知识点,以及灵活多变的思维逻辑。
当然,数组去重还有其他的多种实现方式,欢迎各位小伙伴留言交流!
后记
以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得点赞
、收藏
呦,关注胡哥有话说,学习前端不迷路,欢迎多多留言交流...
胡哥有话说,一个有技术,有情怀的胡哥!现任京东前端攻城狮一枚。
胡哥有话说,专注于大前端技术领域,分享前端系统架构,框架实现原理,最新最高效的技术实践!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Deno 正式发布,彻底弄明白和 node 的区别
前言 Deno 已经正式发布了🎉! 我说这句话时候,是不是很多前端 和 NodeJS 工(码)程(农)师已经按不住自己的40米大刀了。心中的不仅感慨前端是真的会造轮子,有了 node 还不够吗,还没学会 node 又搞了个 deno,node 和 deno 啥区别?! 的确,deno 和 node 形态很相似,要解决的问题似乎也相同,那他们到底有啥区别,这一切究竟是道德的沦丧还是 ry (作者)人性的扭曲,让我们走进本篇文章,一探究竟。 Deno VS Node Node Deno API 引用方式 模块导入 全局对象 模块系统 CommonJS & 新版 node 实验性 ES Module ES Module 浏览器实现 安全 无安全限制 默认安全 Typescript 第三方,如通过 ts-node 支持 原生支持 包管理 npm + node_modules 原生支持 异步操作 回调 Promise 包分发 中心化 npmjs.com 去中心化 import url 入口 package.json 配置 import url 直接引入 打包、测试、格式化 第三方如 e...
- 下一篇
go-fastdfs 分布式文件系统 v1.3.9 发布,修复禁用组同步失败
go-fastdfs 是一个基于 http 协议的分布式文件系统,它基于大道至简的设计理念,一切从简设计,使得它的运维及扩展变得更加简单,它具有高性能、高可靠、无中心、免维护等优点。 v1.3.9 修复禁用组同步失败,windows临时文件删除失效 注意:使用前请认真阅读使用文档或视频教程。 优点 支持curl命令上传 支持浏览器上传 支持HTTP下载 支持多机自动同步 支持断点下载 支持https 支持配置自动生成 支持小文件自动合并(减少inode占用) 支持秒传 支持一键迁移 支持并行体验 支持断点续传(tus) 支持docker部署 支持自监控告警 支持集群文件信息查看 使用通用HTTP协议 无需专用客户端(支持wget,curl等工具) 类fastdfs 高性能 高可靠 无中心设计(所有节点都可以同时读写) 更新历史 v1.3.8 增加 https 支持,增加 0.0.0.0 IP 白名单放行所有内网 v1.3.7 增加上传返回格式 json2,修证生成 google secret 认证 bug v1.3.6 修复并发备份BUG,增加备份队列参数与延迟备份参数 v1.3.5支...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7安装Docker,走上虚拟化容器引擎之路