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 相关文章推荐
Gird事件机制初级读本
Mar 10 Javascript
如何让浏览器支持jquery ajax load 前进、后退功能
Jun 12 Javascript
JS点击链接后慢慢展开隐藏着图片的方法
Feb 17 Javascript
jQuery实现时尚漂亮的弹出式对话框实例
Aug 07 Javascript
jQuery实现倒计时功能 jQuery实现计时器功能
Sep 19 jQuery
详解Vuex管理登录状态
Nov 13 Javascript
详解基于Node.js的HTTP/2 Server实践
May 31 Javascript
Mint-UI时间组件起始时间问题及时间插件使用
Aug 20 Javascript
javascript中函数的写法实例代码详解
Oct 28 Javascript
vue中的适配px2rem示例代码
Nov 19 Javascript
vue实现五子棋游戏
May 28 Javascript
Vue图片裁剪组件实例代码
Jul 02 Vue.js
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
?繁体转换的class
2006/10/09 PHP
php socket方式提交的post详解
2008/07/19 PHP
Thinkphp中的volist标签用法简介
2014/06/18 PHP
Laravel实现构造函数自动依赖注入的方法
2016/03/16 PHP
PHP abstract 抽象类定义与用法示例
2018/05/29 PHP
node.js中的http.response.end方法使用说明
2014/12/14 Javascript
javascript实现全角与半角字符的转换
2015/01/07 Javascript
浅谈JavaScript的Polymer框架中的事件绑定
2015/07/29 Javascript
jQuery扩展+xml实现表单验证功能的方法
2016/12/25 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
2017/02/05 Javascript
vue使用自定义icon图标的方法
2018/05/14 Javascript
Vue编程式跳转的实例代码详解
2019/07/10 Javascript
如何基于JS截获动态代码
2019/12/25 Javascript
[02:15]2014DOTA2国际邀请赛 专访LGD.lin小兔子是大腿
2014/07/14 DOTA
[46:25]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第二局
2016/03/05 DOTA
Python sys.argv用法实例
2015/05/28 Python
Windows上使用virtualenv搭建Python+Flask开发环境
2016/06/07 Python
浅谈python日志的配置文件路径问题
2018/04/28 Python
Numpy 将二维图像矩阵转换为一维向量的方法
2018/06/05 Python
python3解析库lxml的安装与基本使用
2018/06/27 Python
Window 64位下python3.6.2环境搭建图文教程
2018/09/19 Python
Python生成指定数量的优惠码实操内容
2019/06/18 Python
python创建子类的方法分析
2019/11/28 Python
Django Admin后台模型列表页面如何添加自定义操作按钮
2020/11/11 Python
一款利用html5和css3实现的3D立方体旋转效果教程
2016/04/26 HTML / CSS
顶撞领导检讨书
2014/01/29 职场文书
2014年迎新年活动方案
2014/02/19 职场文书
民主生活会剖析材料
2014/09/30 职场文书
领导班子对照检查剖析材料
2014/10/13 职场文书
2015年百日安全活动总结
2015/03/26 职场文书
追悼会悼词大全
2015/06/23 职场文书
少先队大队委竞选口号
2015/12/25 职场文书
《合作意向书》怎么写?
2019/08/20 职场文书
教你怎么用Python监控愉客行车程
2021/04/29 Python
关于React Native 无法链接模拟器的问题
2021/06/21 Javascript
Python爬虫基础之初次使用scrapy爬虫实例
2021/06/26 Python