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 判断页面元素是否存在的代码
Aug 14 Javascript
使用Jquery来实现可以输入值的下拉选单 雏型
Dec 06 Javascript
基于jquery的点击链接插入链接内容的代码
Jul 31 Javascript
自己写的Javascript计算时间差函数
Oct 28 Javascript
javascript中DOM复选框选择用法实例
May 14 Javascript
使用JS组件实现带ToolTip验证框的实例代码
Aug 23 Javascript
javascript变量提升和闭包理解
Mar 12 Javascript
angular项目中bootstrap-datetimepicker时间插件的使用示例
Mar 15 Javascript
微信小程序在ios下Echarts图表不能滑动的问题解决
Jul 10 Javascript
小程序如何在不同设备上自适应生成海报的实现方法
Aug 20 Javascript
js+canvas实现简单扫雷小游戏
Jan 22 Javascript
原生js+canvas实现贪吃蛇效果
Aug 02 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/04/24 PHP
php定时删除文件夹下文件(清理缓存文件)
2013/01/23 PHP
Yii框架调试心得--在页面输出执行sql语句
2014/12/25 PHP
新浪微博OAuth认证和储存的主要过程详解
2015/03/27 PHP
PHP实现清除wordpress里恶意代码
2015/10/21 PHP
PHP格式化MYSQL返回float类型的方法
2016/03/30 PHP
php实现支持中文的文件下载功能示例
2017/08/30 PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
2017/11/17 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
2020/02/27 PHP
Laravel 框架控制器 Controller原理与用法实例分析
2020/04/14 PHP
任意位置显示html菜单
2007/02/01 Javascript
JS获取并操作iframe中元素的方法
2013/03/21 Javascript
JS运动基础框架实例分析
2015/03/03 Javascript
微信公众平台开发教程(六)获取个性二维码的实例
2016/12/02 Javascript
使用微信小程序开发前端【快速入门】
2016/12/05 Javascript
jQuery Validate 校验多个相同name的方法
2017/05/18 jQuery
微信小程序之选项卡的实现方法
2017/09/29 Javascript
JS实现简单的表格增删
2020/01/16 Javascript
Vue的状态管理vuex使用方法详解
2020/02/05 Javascript
Webpack5正式发布,有哪些新特性
2020/10/12 Javascript
Python切换pip安装源的方法详解
2016/11/18 Python
Python装饰器原理与用法分析
2018/04/30 Python
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
pygame实现俄罗斯方块游戏
2018/06/26 Python
解决Django一个表单对应多个按钮的问题
2019/07/18 Python
Python开发之pip安装及使用方法详解
2020/02/21 Python
Python利用pip安装tar.gz格式的离线资源包
2020/09/14 Python
python爬虫请求头的使用
2020/12/01 Python
Shopee印度尼西亚:东南亚与台湾市场最大电商平台
2018/06/17 全球购物
销售高级职员求职信
2013/10/29 职场文书
法人代表任命书范本
2014/06/05 职场文书
向国旗敬礼活动总结
2014/09/27 职场文书
挂靠协议书
2015/01/27 职场文书
JVM钩子函数的使用场景详解
2021/08/23 Java/Android
Sql Server之数据类型详解
2022/02/28 SQL Server
“鬼灭之刃”热度不减,其成功背后的原因是什么?
2022/03/22 日漫