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 相关文章推荐
Jquery AJAX 框架的使用方法
Nov 03 Javascript
js点击页面其它地方将某个显示的DIV隐藏
Jul 12 Javascript
javascript 数字格式化输出的实现代码
Dec 10 Javascript
jquery easyUI中ajax异步校验用户名
Aug 19 Javascript
javascript基础练习之翻转字符串与回文
Feb 20 Javascript
完美实现js选项卡切换效果(二)
Mar 08 Javascript
angular中实现li或者某个元素点击变色的两种方法
Jul 27 Javascript
React Native基础入门之初步使用Flexbox布局
Jul 02 Javascript
浅谈Vue的响应式原理
May 30 Javascript
深入剖析JavaScript instanceof 运算符
Jun 14 Javascript
js实现上传按钮并显示缩略图小轮子
May 04 Javascript
Vue element-ui父组件控制子组件的表单校验操作
Jul 17 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
要会喝咖啡也要会知道咖啡豆
2021/03/03 咖啡文化
PHP 日常开发小技巧
2009/09/23 PHP
yii操作cookie实例简介
2014/07/09 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
2019/02/13 PHP
PHP count_chars()函数讲解
2019/02/14 PHP
BOOM vs RR BO3 第一场2.13
2021/03/10 DOTA
html读出文本文件内容
2007/01/22 Javascript
JavaScript 动态添加表格行 使用模板、标记
2009/10/24 Javascript
JavaScript中的Array对象使用说明
2011/01/17 Javascript
jQuery下实现等待指定元素加载完毕(可改成纯js版)
2013/07/11 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
2016/04/12 Javascript
jQuery短信验证倒计时功能实现方法详解
2016/05/25 Javascript
AngularJS基础 ng-model 指令详解及示例代码
2016/08/02 Javascript
JavaScript数组的5种迭代方法
2017/09/29 Javascript
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
JavaScript学习笔记之基于定时器实现图片无缝滚动功能详解
2019/01/09 Javascript
使用JavaScript解析URL的方法示例
2019/03/01 Javascript
Layui动态生成select下拉选择框不显示的解决方法
2019/09/24 Javascript
JavaScript实现多个物体同时运动
2020/03/12 Javascript
详解ES6 CLASS在微信小程序中的应用实例
2020/04/24 Javascript
IDEA配置jQuery, $符号不再显示黄色波浪线的问题
2020/10/09 jQuery
[01:13:01]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第三场
2018/04/05 DOTA
python实现调用其他python脚本的方法
2014/10/05 Python
Python中矩阵创建和矩阵运算方法
2018/08/04 Python
python实现n个数中选出m个数的方法
2018/11/13 Python
python web自制框架之接受url传递过来的参数实例
2018/12/17 Python
Python类装饰器实现方法详解
2018/12/21 Python
Python用input输入列表的实例代码
2020/02/07 Python
TobyDeals美国:在电子产品上获得最好的优惠和折扣
2019/08/11 全球购物
药学专业大专生的自我评价
2013/12/12 职场文书
分层教学实施方案
2014/03/19 职场文书
教师岗位聘任书范文
2014/03/29 职场文书
机关党员公开承诺书
2014/08/30 职场文书
2014教师“四风问题”对照检查材料思想汇报
2014/09/16 职场文书
稽核岗位职责
2015/02/10 职场文书