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中层次选择器用法实例详解
May 18 Javascript
JavaScript实现将UPC转换成ISBN的方法
May 26 Javascript
跟我学习javascript的undefined与null
Nov 17 Javascript
jquery获取select选中值的方法分析
Dec 22 Javascript
基于jquery实现动态竖向柱状条特效
Feb 12 Javascript
jquery滚动条插件(可以自定义)
Dec 11 Javascript
JavaScript自动点击链接 防止绕过浏览器访问的方法
Jan 19 Javascript
jQuery事件blur()方法的使用实例讲解
Mar 30 jQuery
使用 Element UI Table 的 slot-scope方法
Oct 10 Javascript
详解vue中多个有顺序要求的异步操作处理
Oct 29 Javascript
Vue使用路由钩子拦截器beforeEach和afterEach监听路由
Nov 16 Javascript
关于JavaScript 中 if包含逗号表达式
Nov 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
ThinkPHP3.1新特性之对页面压缩输出的支持
2014/06/19 PHP
php+ajax实现文章自动保存的方法
2014/12/30 PHP
javascript 面向对象全新理练之继承与多态
2009/12/03 Javascript
详解Javascript模板引擎mustache.js
2016/01/20 Javascript
jQuery操作属性和样式详解
2016/04/13 Javascript
浅谈javascript alert和confirm的美化
2016/12/15 Javascript
jQuery实现的checkbox级联选择下拉菜单效果示例
2016/12/26 Javascript
AngularJS实现根据不同条件显示不同控件
2017/04/20 Javascript
js模拟百度模糊搜索的实例
2017/08/04 Javascript
深入浅析Vue不同场景下组件间的数据交流
2017/08/15 Javascript
vue调用语音播放的方法
2019/09/27 Javascript
JavaScript 变量,数据类型基础实例详解【变量、字符串、数组、对象等】
2020/01/04 Javascript
Vue computed 计算属性代码实例
2020/04/22 Javascript
通过实例解析vuejs如何实现调试代码
2020/07/16 Javascript
wxPython事件驱动实例详解
2014/09/28 Python
Python2.6版本中实现字典推导 PEP 274(Dict Comprehensions)
2015/04/28 Python
Python工程师面试题 与Python Web相关
2016/01/14 Python
urllib和BeautifulSoup爬取维基百科的词条简单实例
2018/01/17 Python
Python输入二维数组方法
2018/04/13 Python
对Python 窗体(tkinter)树状数据(Treeview)详解
2018/10/11 Python
Python实现分段线性插值
2018/12/17 Python
Python实现性能自动化测试竟然如此简单
2019/07/30 Python
python如何对链表操作
2020/10/10 Python
使用HTML和CSS实现的标签云效果(附demo)
2021/02/03 HTML / CSS
eBay德国站:eBay.de
2017/09/14 全球购物
init进程的作用
2015/08/20 面试题
升职自荐信范文
2013/10/05 职场文书
学生党员思想汇报
2013/12/28 职场文书
美丽乡村建设实施方案
2014/03/23 职场文书
离婚财产处理协议书
2014/09/30 职场文书
群众路线四风对照检查材料
2014/11/04 职场文书
行政申诉状范文
2015/05/20 职场文书
2016个人廉洁自律承诺书
2016/03/25 职场文书
2019升学宴主持词范本5篇
2019/10/09 职场文书
golang 接口嵌套实现复用的操作
2021/04/29 Golang
MySQL中的全表扫描和索引树扫描
2022/05/15 MySQL