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 学习笔记 选择器之一
Jul 23 Javascript
JQuery设置获取下拉菜单某个选项的值(比较全)
Aug 05 Javascript
gridview生成时如何去掉style属性中的border-collapse
Sep 30 Javascript
微信小程序 获取相册照片实例详解
Nov 16 Javascript
折叠菜单及选择器的运用
Feb 03 Javascript
AngularJS路由Ui-router模块用法示例
May 29 Javascript
javascript数组定义的几种方法
Oct 06 Javascript
jQuery 禁止表单用户名、密码自动填充功能
Oct 30 jQuery
详解JavaScript 中 if / if...else...替换方式
Jul 15 Javascript
详解多页应用 Webpack4 配置优化与踩坑记录
Oct 16 Javascript
Vue动态路由缓存不相互影响的解决办法
Feb 19 Javascript
JavaScript实现京东快递单号查询
Nov 30 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
Re:从零开始的异世界生活 第2季 开播啦
2020/07/24 日漫
Thinkphp中的volist标签用法简介
2014/06/18 PHP
php自动获取关键字的方法
2015/01/06 PHP
PHP入门教程之正则表达式基本用法实例详解(正则匹配,搜索,分割等)
2016/09/11 PHP
javascript 3d 逐侦产品展示(核心精简)
2014/03/26 Javascript
JavaScript框架(iframe)操作总结
2014/04/16 Javascript
通过Jquery.cookie.js实现展示浏览网页的历史记录超管用
2015/10/23 Javascript
js实现密码强度检验
2017/01/15 Javascript
Vue.js实现一个漂亮、灵活、可复用的提示组件示例
2017/03/17 Javascript
使用vue与jquery实时监听用户输入状态的操作代码
2017/09/19 jQuery
React数据传递之组件内部通信的方法
2017/12/31 Javascript
在vue中使用jointjs的方法
2018/03/24 Javascript
layui实现下拉框三级联动
2019/07/26 Javascript
express框架中使用jwt实现验证的方法
2019/08/25 Javascript
[01:28:24]NAVI vs VG Supermajor 败者组 BO3 第三场 6.5
2018/06/06 DOTA
Python使用Redis实现作业调度系统(超简单)
2016/03/22 Python
Python 3实战爬虫之爬取京东图书的图片详解
2017/10/09 Python
python 反向输出字符串的方法
2018/07/16 Python
Python matplotlib生成图片背景透明的示例代码
2019/08/30 Python
在tensorflow中设置使用某一块GPU、多GPU、CPU的操作
2020/02/07 Python
Python类中self参数用法详解
2020/02/13 Python
使用已经得到的keras模型识别自己手写的数字方式
2020/06/29 Python
Python提取视频中图片的示例(按帧、按秒)
2020/10/22 Python
新西兰最大的品牌运动鞋购物网站:Platypus NZ
2017/10/27 全球购物
医学生个人求职信范文
2013/09/24 职场文书
环境科学专业个人求职信
2013/12/15 职场文书
大学生求职自我评价
2014/01/16 职场文书
大学生素质拓展活动方案
2014/02/11 职场文书
党员志愿者活动总结
2014/06/26 职场文书
模具设计与制造专业求职信
2014/07/19 职场文书
党的群众路线教育实践活动心得体会范文
2014/11/05 职场文书
解除劳动合同证明书模板
2014/11/20 职场文书
安全生产先进个人事迹材料
2014/12/30 职场文书
人民检察院起诉书
2015/05/20 职场文书
docker-compose部署Yapi的方法
2022/04/08 Servers
Android开发手册Chip监听及ChipGroup监听
2022/06/10 Java/Android