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 相关文章推荐
Add Formatted Text to a Word Document
Jun 15 Javascript
JavaScipt基本教程之JavaScript语言的基础
Jan 16 Javascript
javascript demo 基本技巧
Dec 18 Javascript
JS学习之一个简易的日历控件
Mar 24 Javascript
在jQuery中 关于json空对象筛选替换
Apr 15 Javascript
AngularJS过滤器详解及示例代码
Aug 16 Javascript
BootStrap轮播HTML代码(推荐)
Dec 10 Javascript
React根据宽度自适应高度的示例代码
Oct 11 Javascript
Vue Cli 3项目使用融云IM实现聊天功能的方法
Apr 19 Javascript
微信小程序绘制图片发送朋友圈
Jul 25 Javascript
layui 富文本编辑器和textarea值的相互传递方法
Sep 18 Javascript
JavaScript实现点击切换功能
Jan 27 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
解析zend studio中直接导入svn中的项目的方法步骤
2013/06/21 PHP
php格式输出文件var_export函数实例
2014/11/15 PHP
php.ini中的request_order推荐设置
2015/05/10 PHP
php+iframe 实现上传文件功能示例
2020/03/04 PHP
JS写的数字拼图小游戏代码[学习参考]
2008/10/29 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
JavaScript优化专题之Loading and Execution加载和运行
2016/01/20 Javascript
基于jquery fly插件实现加入购物车抛物线动画效果
2016/04/05 Javascript
详解XMLHttpRequest(一)同步请求和异步请求
2016/09/14 Javascript
详解NODEJS的http实现
2018/01/04 NodeJs
解决Vue打包之后文件路径出错的问题
2018/03/06 Javascript
Vue的H5页面唤起支付宝支付功能
2019/04/18 Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
2020/08/03 Javascript
基于JS实现操作成功之后自动跳转页面
2020/09/25 Javascript
小程序实现列表倒计时功能
2021/01/29 Javascript
[02:28]DOTA2英雄基础教程 狼人
2013/12/23 DOTA
在Python下尝试多线程编程
2015/04/28 Python
Python自动扫雷实现方法
2015/07/25 Python
python脚本设置系统时间的两种方法
2016/02/21 Python
图文讲解选择排序算法的原理及在Python中的实现
2016/05/04 Python
书单|人生苦短,你还不用python!
2017/12/29 Python
python smtplib发送带附件邮件小程序
2018/05/22 Python
python的schedule定时任务模块二次封装方法
2019/02/19 Python
Python-Flask:动态创建表的示例详解
2019/11/22 Python
Python手绘可视化工具cutecharts使用实例
2019/12/05 Python
Django如何使用jwt获取用户信息
2020/04/21 Python
matplotlib基础绘图命令之imshow的使用
2020/08/13 Python
Python爬虫scrapy框架Cookie池(微博Cookie池)的使用
2021/01/13 Python
Tiqets荷兰:出售欧洲最美丽的景点和博物馆门票
2018/01/09 全球购物
WEB控件及HTML服务端控件能否调用客户端方法?如果能,请解释如何调用?
2015/08/25 面试题
干部行政关系介绍信
2014/01/17 职场文书
大专生毕业的自我评价
2014/02/06 职场文书
职场:企业印章管理制度(模板)
2019/10/18 职场文书
导游词之江苏同里古镇
2019/11/18 职场文书
Axios取消重复请求的方法实例详解
2021/06/15 Javascript
Python办公自动化PPT批量转换操作
2021/09/15 Python