javascript数组去掉重复


Posted in Javascript onMay 12, 2011

总得来说面试的过程还是收获了不少,主要是认清自己的差距到底有多大,知识面到底有多窄,适当打击一下自信心还是有必要的。在这里做一次全面的总结,关于javascript的数组去重问题。

考虑一个问题由简到繁相对容易接受一点,首先假设要去重的数组是比较简单的,例如:

var arr=[1,2,2,3,'5',6,5,'',' ']

这个数组只包含了数字,字符串两种类型。我们给数组原型上面添加去重的方法distinct,用第一种很容易想到的方法来实现,当然也是很笨很直接的,把这个数组复制一份然后循环两个数组,对比当前值与后面所有的值是否相等,如果与后面所有值都不等则把该值存到新数组里,如此最后再返回该新数组。方法如下:
//第一种方法 
Array.prototype.distinct=function(){ 
var clone,newArr=[],n=0; 
if(this.length<2)return; 
clone=this; 
for(var i=0,len=this.length;i<len;i++){ 
for(var j=i+1,len2=clone.length;j<len2;j++){ 
if(this[i]!==clone[j]){ 
n++; 
} 
} 
if(n==(len-i-1)){ 
newArr.push(this[i]) 
} 
n=0; 
} 
return newArr; 
} 
console.log([1,2,2,3,'5',6,5,'',' '].distinct()); 
/*获得被check的radio的值*/ 
function GetRadioValue(RadioName){ 
var obj; 
obj=document.getElementsByName(RadioName); 
if(obj!=null){ 
var i; 
for(i=0;i<obj.length;i++){ 
if(obj[i].checked){ 
return obj[i].value; 
} 
} 
} 
return null; 
} /*设置被选中属性*/ 
function SetRadioCheck(RadioName,i){ 
var obj; 
obj=document.getElementsByName(RadioName); 
obj[i].setAttribute("checked","checked"); 
}

基本可以满足我们的需求,对这样简单的类型比较确实不用费太多的脑经,但如果数组很长呢?如此遍历数组,数组长度为n,那么时间复杂度为n*n。显然该方法性能还有待提升。接下来是第二种方法,用到数组排序,在排序的过程去除重复的值。
//第二种方法 
Array.prototype.distinct=function(){ 
var newArr=this.concat().sort(),self=this; 
newArr.sort(function(a,b){ 
var n; 
if(a===b){ 
n=self.indexOf(a); 
self.splice(n,1); 
} 
}); 
return self; 
} 
console.log([1,2,2,3,'5',6,5,6,6,15,5,'5',5,'',' '].distinct());

这样代码看起来似乎短了很多,甚至连一个for循环都没有,但是sort得效率也高不到哪里去。再来看看第三种实现方法,用到的对象属性不会重名的原理
//第三种方法 
Array.prototype.distinct=function(){ 
var newArr=[],obj={}; 
for(var i=0,len=this.length;i<len;i++){ 
if(!obj[this[i]]){ 
newArr.push(this[i]); 
obj[this[i]]='new'; 
} 
} 
return newArr; 
} 
console.log([1,2,2,3,'5',6,5,6,6,15,5,'5',5,'',' '].distinct());

第三种方法运行看下结果,会发现跟上面的方法实现的结果不一致,细看原来它把数字5和字符串5当成重复的值给去掉了。看来类型必须保存起来然后再判断是否相等,这样便有了下面的第三种方法的补充版
//第三种方法补充版 
Array.prototype.distinct=function(){ 
var newArr=[],obj={}; 
for(var i=0,len=this.length;i<len;i++){ 
if(!obj[typeof(this[i])+this[i]]){ 
newArr.push(this[i]); 
obj[typeof(this[i])+this[i]]='new'; 
} 
} 
return newArr; 
}

上面举的例子是很简单的类型,我们拿更复杂的类型来测试一下
console.log([1,null,2,{a:'vc'},{},'5',6,5,6,{a:'vv'},15,5,'5',5,'',' ',[1],[1],[1,2],,].distinct());

发现{a:'vc'},{},{a:'vv'}这些不同的对象还是会被剔除掉,如果数组里面有对象则要继续遍历对象里面的属性和值,继续第三种方法的加强
//第三种方法加强版 
Array.prototype.distinct=function(){ 
var sameObj=function(a,b){ 
var tag = true; 
if(!a||!b)return false; 
for(var x in a){ 
if(!b[x]) 
return false; 
if(typeof(a[x])==='object'){ 
tag=sameObj(a[x],b[x]); 
}else{ 
if(a[x]!==b[x]) 
return false; 
} 
} 
return tag; 
} 
var newArr=[],obj={}; 
for(var i=0,len=this.length;i<len;i++){ 
if(!sameObj(obj[typeof(this[i])+this[i]],this[i])){ 
newArr.push(this[i]); 
obj[typeof(this[i])+this[i]]=this[i]; 
} 
} 
return newArr; 
}

用上面的例子测试发现基本木有问题,当然测试还可以更加变态更加纠缠,这里就不去深究了,目前来看此篇方法在网上属于比较齐全的,如果有更好更完善的方法请不吝赐教。
Javascript 相关文章推荐
用函数式编程技术编写优美的 JavaScript_ibm
May 16 Javascript
『JavaScript』限制Input只能输入数字实现思路及代码
Apr 22 Javascript
基于JavaScript实现瀑布流效果(循环渐近)
Jan 27 Javascript
easyui取消表单实时验证,提交时统一验证的简单实例
Nov 07 Javascript
JavaScript面向对象分层思维全面解析
Nov 22 Javascript
bootstrap网格系统使用方法解析
Jan 13 Javascript
纯JS实现轮播图
Feb 22 Javascript
AngularJS实现的JSONP跨域访问数据传输功能详解
Jul 20 Javascript
JS基于设计模式中的单例模式(Singleton)实现封装对数据增删改查功能
Feb 06 Javascript
vue项目搭建以及全家桶的使用详细教程(小结)
Dec 19 Javascript
layui实现鼠标移动到单元格上显示数据的方法
Sep 11 Javascript
AngularJs的$http发送POST请求,php无法接收Post的数据问题及解决方案
Aug 13 Javascript
javascript 弹出层组件(升级版)
May 12 #Javascript
ExtJS4 组件化编程,动态加载,面向对象,Direct
May 12 #Javascript
关于js获取radio和select的属性并控制的代码
May 12 #Javascript
js 第二代身份证号码的验证机制代码
May 12 #Javascript
基于JQuery的动态删除Table表格的行和列的代码
May 12 #Javascript
五个jQuery图片画廊插件 推荐
May 12 #Javascript
JavaScript 继承使用分析
May 12 #Javascript
You might like
PHP采集腾讯微博的实现代码
2012/01/19 PHP
利用php绘制饼状图的实现代码
2013/06/07 PHP
php实现阿拉伯数字和罗马数字相互转换的方法
2015/04/17 PHP
PHP限制HTML内容中图片必须是本站的方法
2015/06/16 PHP
php中Snoopy类用法实例
2015/06/19 PHP
PHP实现防止表单重复提交功能【基于token验证】
2018/05/24 PHP
Web版彷 Visual Studio 2003 颜色选择器
2007/01/09 Javascript
多引号嵌套的变量命名的问题
2014/05/09 Javascript
理解javascript回调函数
2014/12/28 Javascript
jQuery实现的表头固定效果实例【附完整demo源码下载】
2016/08/01 Javascript
AngularJS 整理一些优化的小技巧
2016/08/18 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
bootstrapValidator 重新启用提交按钮的方法
2017/02/20 Javascript
vue.js 使用v-if v-else发现没有执行解决办法
2017/05/15 Javascript
用js实现每隔一秒刷新时间的实例(含年月日时分秒)
2017/10/25 Javascript
JQuery实现table中tr上移下移的示例(超简单)
2018/01/08 jQuery
nodejs 如何手动实现服务器
2018/08/20 NodeJs
TypeScript中的方法重载详解
2019/04/12 Javascript
React Ant Design树形表格的复杂增删改操作
2020/11/02 Javascript
[01:03]DOTA2新的征程 你的脚印值得踏上
2014/08/13 DOTA
[56:00]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第二场
2018/04/10 DOTA
python文件操作之目录遍历实例分析
2015/05/20 Python
Scrapy基于selenium结合爬取淘宝的实例讲解
2018/06/13 Python
python 移动图片到另外一个文件夹的实例
2019/01/10 Python
解决Python 命令行执行脚本时,提示导入的包找不到的问题
2019/01/19 Python
Django Serializer HiddenField隐藏字段实例
2020/03/31 Python
在pycharm中关掉ipython console/PyDev操作
2020/06/09 Python
Python创建临时文件和文件夹
2020/08/05 Python
简历的个人自我评价范文
2014/01/03 职场文书
气象学专业个人求职信
2014/04/22 职场文书
会计专业自荐信
2014/06/03 职场文书
2014年服务员工作总结
2014/11/18 职场文书
2014年少先队工作总结
2014/12/03 职场文书
写给同学的新学期寄语
2015/02/27 职场文书
村党组织公开承诺书
2015/04/30 职场文书
高中运动会前导词
2015/07/20 职场文书