js 数组去重的四种实用方法


Posted in Javascript onSeptember 09, 2014

面试前端必须准备的一个问题:怎样去掉Javascript的Array的重复项。据我所知,百度、腾讯、盛大等都在面试里出过这个题目。这个问题看起来简单,但是其实暗藏杀机。 考的不仅仅是实现这个功能,更能看出你对计算机程序执行的深入理解。

我总共想出了三种算法来实现这个目的:

Array.prototype.unique1 = function()
{
var n = []; //一个新的临时数组
for(var i = 0; i < this.length; i++) //遍历当前数组
{
//如果当前数组的第i已经保存进了临时数组,那么跳过,
//否则把当前项push到临时数组里面
if (n.indexOf(this[i]) == -1) n.push(this[i]);
}
return n;
}

Array.prototype.unique2 = function()
{
var n = {},r=[]; //n为hash表,r为临时数组
for(var i = 0; i < this.length; i++) //遍历当前数组
{
if (!n[this[i]]) //如果hash表中没有当前项
{
n[this[i]] = true; //存入hash表
r.push(this[i]); //把当前数组的当前项push到临时数组里面
}
}
return r;
}

Array.prototype.unique3 = function()
{
var n = [this[0]]; //结果数组
for(var i = 1; i < this.length; i++) //从第二项开始遍历
{
//如果当前数组的第i项在当前数组中第一次出现的位置不是i,
//那么表示第i项是重复的,忽略掉。否则存入结果数组
if (this.indexOf(this[i]) == i) n.push(this[i]);
}
return n;
}

其中第1种和第3种方法都用到了数组的indexOf方法。此方法的目的是寻找存入参数在数组中第一次出现的位置。很显然,js引擎在实现这个方法的时候会遍历数组直到找到目标为止。所以此函数会浪费掉很多时间。 而第2中方法用的是hash表。把已经出现过的通过下标的形式存入一个object内。下标的引用要比用indexOf搜索数组快的多。

为了判断这三种方法的效率如何,我做了一个测试程序,生成一个10000长度的随机数组成的数组,然后分别用几个方法来测试执行时间。 结果表明第二种方法远远快于其他两种方法。 但是内存占用方面应该第二种方法比较多,因为多了一个hash表。这就是所谓的空间换时间。 就是这个测试页面,你也可以去看看。

我写了第四种方法:

Array.prototype.unique4 = function()
{
this.sort();
var re=[this[0]];
for(var i = 1; i < this.length; i++)
{
if( this[i] !== re[re.length-1])
{
re.push(this[i]);
}
}
return re;
}

这个方法的思路是先把数组排序,然后比较相邻的两个值。 排序的时候用的JS原生的sort方法,JS引擎内部应该是用的快速排序吧。 最终测试的结果是此方法运行时间平均是第二种方法的三倍左右,不过比第一种和第三种方法快了不少。

Javascript 相关文章推荐
jquery ajax执行后台方法
Mar 18 Javascript
JS 屏蔽键盘不可用与鼠标右键不可用的方法
Nov 18 Javascript
js中继承的几种用法总结(apply,call,prototype)
Dec 26 Javascript
jQuery实现点击该行即可删除HTML表格行
Oct 17 Javascript
程序员必知35个jQuery 代码片段
Nov 05 Javascript
jQuery实现只允许输入数字和小数点的方法
Mar 02 Javascript
借助node实战JSONP跨域实例
Mar 30 Javascript
完美解决axios跨域请求出错的问题
Feb 05 Javascript
微信小程序的mpvue框架快速上手指南
May 15 Javascript
基于Node.js的大文件分片上传示例
Jun 19 Javascript
微信小程序的授权实现过程解析
Aug 02 Javascript
JavaScript前后端JSON使用方法教程
Nov 23 Javascript
jQuery源码分析之jQuery中的循环技巧详解
Sep 06 #Javascript
10分钟学会写Jquery插件实例教程
Sep 06 #Javascript
页面加载完后自动执行一个方法的js代码
Sep 06 #Javascript
jquery mobile页面跳转后样式丢失js失效的解决方法
Sep 06 #Javascript
禁止iframe脚本弹出的窗口覆盖了父窗口的方法
Sep 06 #Javascript
js和jquery中循环的退出和继续学习记录
Sep 06 #Javascript
jquery实现html页面 div 假分页有原理有代码
Sep 06 #Javascript
You might like
如何提高MYSQL数据库的查询统计速度 select 索引应用
2007/04/11 PHP
php 备份数据库代码(生成word,excel,json,xml,sql)
2013/06/23 PHP
thinkphp模板输出技巧汇总
2014/11/24 PHP
PHP构造二叉树算法示例
2017/06/21 PHP
php和asp语法上的区别总结
2019/05/12 PHP
jQuery队列控制方法详解queue()/dequeue()/clearQueue()
2010/12/02 Javascript
浅析javascript闭包 实例分析
2010/12/25 Javascript
浅谈Javascript鼠标和滚轮事件
2012/06/27 Javascript
使用jQuery时Form表单元素ID和name命名大忌
2014/03/06 Javascript
使用javascript实现雪花飘落的效果
2015/01/13 Javascript
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
2015/04/12 Javascript
Node.js与Sails ~项目结构与Mvc实现及日志机制
2015/10/14 Javascript
浅谈js里面的InttoStr和StrtoInt
2016/06/14 Javascript
Vue前后端不同端口的实现方法
2018/09/19 Javascript
javascript实现切割轮播效果
2019/11/28 Javascript
jQuery实现获取多选框的值示例
2020/02/07 jQuery
vue基础知识--axios合并请求和slot
2020/06/04 Javascript
python使用socket远程连接错误处理方法
2015/04/29 Python
Python中扩展包的安装方法详解
2017/06/14 Python
Python实现求解括号匹配问题的方法
2018/04/17 Python
浅谈pycharm出现卡顿的解决方法
2018/12/03 Python
Django如何在不停机的情况下创建索引
2020/08/02 Python
无需JS和jQuery代码实现CSS3鼠标浮动放大图片
2016/11/21 HTML / CSS
Html5大文件断点续传实现方法
2015/12/05 HTML / CSS
HTML5离线应用与客户端存储的实现
2018/05/03 HTML / CSS
职业生涯规划书基本格式
2014/01/06 职场文书
给市场的环保建议书
2014/05/14 职场文书
小学五一劳动节活动总结
2015/02/09 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
岗位聘任协议书
2015/09/21 职场文书
商务信函英语问候语
2015/11/10 职场文书
学习习近平主席讲话心得体会
2016/01/20 职场文书
2016国庆促销广告语
2016/01/28 职场文书
关于应聘教师的自荐信
2016/01/28 职场文书
HTML怎么设置下划线?html文字加下划线方法
2021/12/06 HTML / CSS
Java Lambda表达式常用的函数式接口
2022/04/07 Java/Android