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 相关文章推荐
js实现div的切换特效上一个下一个
Feb 11 Javascript
AngularJS指令与控制器之间的交互功能示例
Dec 14 Javascript
Vue.js实现多条件筛选、搜索、排序及分页的表格功能
Nov 24 Javascript
Angular 4依赖注入学习教程之组件服务注入(二)
Jun 04 Javascript
关于webpack代码拆分的解析
Jul 20 Javascript
详解win7 cmd执行vue不是内部命令的解决方法
Jul 27 Javascript
老生常谈ES6中的类
Jul 31 Javascript
微信小程序自定义对话框弹出和隐藏动画
Jul 19 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
Oct 24 Javascript
Vue-cli3.X使用px2 rem遇到的问题及解决方法
Aug 08 Javascript
微信小程序使用npm包的方法步骤
Aug 13 Javascript
vue中 v-for循环的用法详解
Feb 19 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
学习discuz php 引入文件的方法DISCUZ_ROOT
2009/06/21 PHP
php小型企业库存管理系统的设计与实现代码
2011/05/16 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
PHP 5.3新增魔术方法__invoke概述
2014/07/23 PHP
jquery 常用操作整理 基础入门篇
2009/10/14 Javascript
关于JavaScript中原型继承中的一点思考
2012/07/25 Javascript
JSONP获取Twitter和Facebook文章数的具体步骤
2014/02/24 Javascript
JavaScript中获取鼠标位置相关属性总结
2014/10/11 Javascript
Jquery简单实现GridView行高亮的方法
2015/06/15 Javascript
使用nodejs中httpProxy代理时候出现404异常的解决方法
2016/08/15 NodeJs
jQuery实现表格文本框淡入更改值后淡出效果
2016/09/27 Javascript
详解node如何让一个端口同时支持https与http
2017/07/04 Javascript
jQuery代码优化方法总结
2018/01/29 jQuery
微信小程序实时聊天WebSocket
2018/07/05 Javascript
详解Vue中使用Axios拦截器
2019/04/22 Javascript
Vue 幸运大转盘实现思路详解
2019/05/06 Javascript
如何用原生js写一个弹窗消息提醒插件
2019/05/24 Javascript
vue.js中ref和$refs的使用及示例讲解
2019/08/14 Javascript
何时/使用 Vue3 render 函数的教程详解
2020/07/25 Javascript
vue-cli3访问public文件夹静态资源报错的解决方式
2020/09/02 Javascript
[53:21]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-CDEC
2014/05/22 DOTA
[52:27]2018DOTA2亚洲邀请赛 3.31 小组赛B组 paiN vs Secret
2018/04/01 DOTA
在Python的Django框架中创建语言文件
2015/07/27 Python
浅谈五大Python Web框架
2017/03/20 Python
修改 CentOS 6.x 上默认Python的方法
2019/09/06 Python
python 利用pyttsx3文字转语音过程详解
2019/09/25 Python
利用HTML5中Geolocation获取地理位置调用Google Map API在Google Map上定位
2013/01/23 HTML / CSS
Giglio英国站:意大利奢侈品购物网
2018/03/06 全球购物
小橄榄树:Le Petit Olivier
2018/04/23 全球购物
Public Desire美国/加拿大:全球性的在线鞋类品牌
2018/12/17 全球购物
恒华伟业笔试面试题
2015/02/26 面试题
活动总结报告格式
2014/05/09 职场文书
维稳承诺书
2015/01/20 职场文书
2015年感恩母亲节活动方案
2015/05/04 职场文书
php修改word的实例方法
2021/11/17 PHP
Python TypeError: ‘float‘ object is not subscriptable错误解决
2022/12/24 Python