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 相关文章推荐
Javascript 验证上传图片大小[客户端]
Aug 01 Javascript
asp.net+js 实现无刷新上传解析csv文件的代码
May 17 Javascript
js(JavaScript)实现TAB标签切换效果的简单实例
Feb 26 Javascript
jQuery实现自定义下拉列表
Jan 05 Javascript
JavaScript事件委托实例分析
May 26 Javascript
从零开始学习Node.js系列教程五:服务器监听方法示例
Apr 13 Javascript
vue获取DOM元素并设置属性的两种实现方法
Sep 30 Javascript
Three.js基础学习教程
Nov 16 Javascript
使用Angular自定义字段校验指令的方法示例
Feb 01 Javascript
深入理解 JS 垃圾回收
Jun 03 Javascript
JQuery事件委托(适用于给动态生成的脚本元素添加事件)
Feb 01 jQuery
浅谈Vue2.4.0 $attrs与inheritAttrs的具体使用
Mar 08 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
phpMyAdmin安装并配置允许空密码登录
2015/07/04 PHP
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
laravel请求参数校验方法
2019/10/10 PHP
JavaScript的document对象和window对象详解
2010/12/30 Javascript
基于jquery可配置循环左右滚动例子
2011/09/09 Javascript
jquery ajax学习笔记2 使用XMLHttpRequest对象的responseXML
2011/10/16 Javascript
AngularJs学习第八篇 过滤器filter创建
2016/06/08 Javascript
JS提示:Uncaught SyntaxError:Unexpected token ) 错误的解决方法
2016/08/19 Javascript
手机端 HTML5使用photoswipe.js仿微信朋友圈图片放大效果
2016/08/25 Javascript
jQuery File Upload文件上传插件使用详解
2016/12/06 Javascript
js仿百度音乐全选操作
2017/01/13 Javascript
vue-router跳转页面的方法
2017/02/09 Javascript
Vue代码分割懒加载的实现方法
2017/11/23 Javascript
vue2.0实现前端星星评分功能组件实例代码
2018/02/12 Javascript
JS扩展String.prototype.format字符串拼接的功能
2018/03/09 Javascript
小程序开发踩坑:页面窗口定位(相对于浏览器定位)(推荐)
2019/04/25 Javascript
[16:19]教你分分钟做大人——风暴之灵
2015/03/11 DOTA
python3序列化与反序列化用法实例
2015/05/26 Python
python 读写txt文件 json文件的实现方法
2016/10/22 Python
Python学习_几种存取xls/xlsx文件的方法总结
2018/05/03 Python
Python3模拟curl发送post请求操作示例
2019/05/03 Python
简单了解Python3里的一些新特性
2019/07/13 Python
在pycharm下设置自己的个性模版方法
2019/07/15 Python
简单了解如何封装自己的Python包
2020/07/08 Python
CSS中几个与换行有关的属性简明总结
2014/04/15 HTML / CSS
CSS3实现线性渐变用法示例代码详解
2020/08/07 HTML / CSS
全球知名巧克力品牌:Godiva
2016/07/22 全球购物
高三自我鉴定
2013/10/23 职场文书
两年的个人工作自我评价
2014/01/10 职场文书
物业管理工作方案
2014/05/10 职场文书
园林专业毕业生自荐信
2014/07/04 职场文书
人事经理岗位职责范本
2014/08/04 职场文书
厉行节约工作总结
2015/08/12 职场文书
商业计划书如何写?关键问题有哪些?
2019/07/11 职场文书
七个Python必备的GUI库
2021/04/27 Python
教你如何用cmd快速登录服务器
2022/06/10 Servers