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与jquery的多组处理, 仅展开一个区块的折叠效果
Jan 09 Javascript
解析javascript 实用函数的使用详解
May 10 Javascript
js有序数组的连接问题
Oct 01 Javascript
JavaScript弹出窗口方法汇总
Aug 12 Javascript
js实现鼠标悬浮给图片加边框的方法
Jan 30 Javascript
javascript实现俄罗斯方块游戏的思路和方法
Apr 27 Javascript
JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)
Oct 10 Javascript
vue项目中用cdn优化的方法
Jan 03 Javascript
Node.js进阶之核心模块https入门
May 23 Javascript
JavaScript实现简单轮播图效果
Dec 01 Javascript
微信小程序发送短信验证码完整实例
Jan 07 Javascript
vue搜索和vue模糊搜索代码实例
May 07 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实现读取和编写XML DOM代码
2010/04/07 PHP
通过table标签,PHP输出EXCEL的实现方法
2013/07/24 PHP
php中magic_quotes_gpc对unserialize的影响分析
2014/12/16 PHP
微信支付开发订单查询实例
2016/07/12 PHP
PHP互换两个变量值的方法(不用第三变量)
2016/11/14 PHP
Laravel框架用户登陆身份验证实现方法详解
2017/09/14 PHP
PHP连接SQL Server的方法分析【基于thinkPHP5.1框架】
2019/05/06 PHP
Centos7 Yum安装PHP7.2流程教程详解
2019/07/02 PHP
Flash+XML滚动新闻代码 无图片 附源码下载
2007/11/22 Javascript
JQuery触发事件例如click
2013/09/11 Javascript
jQuery实现鼠标单击网页文字后在文本框显示的方法
2015/05/06 Javascript
jQuery获取DOM节点实例分析(2种方式)
2015/12/15 Javascript
jQuery插件WebUploader实现文件上传
2016/11/07 Javascript
浅谈react-router HashRouter和BrowserRouter的使用
2017/12/29 Javascript
javascript数据结构之多叉树经典操作示例【创建、添加、遍历、移除等】
2018/08/01 Javascript
微信小程序module.exports模块化操作实例浅析
2018/12/20 Javascript
详解vue中router-link标签所必备了解的属性
2019/04/15 Javascript
vue 调用 RESTful风格接口操作
2020/08/11 Javascript
[03:00]DOTA2-DPC中国联赛1月18日Recap集锦
2021/03/11 DOTA
Python 条件判断的缩写方法
2008/09/06 Python
Python3 正在毁灭 Python的原因分析
2014/11/28 Python
Python运算符重载用法实例
2015/05/28 Python
Python卸载模块的方法汇总
2016/06/07 Python
python搭建虚拟环境的步骤详解
2016/09/27 Python
Python OpenCV实现图片上输出中文
2018/01/22 Python
Python3中编码与解码之Unicode与bytes的讲解
2019/02/28 Python
Python实现括号匹配方法详解
2020/02/10 Python
详解pandas获取Dataframe元素值的几种方法
2020/06/14 Python
解决Pyinstaller打包软件失败的一个坑
2021/03/04 Python
社保委托书怎么写
2014/08/02 职场文书
房产授权委托书范本
2014/09/22 职场文书
爱心捐书倡议书
2015/04/27 职场文书
JavaWeb Servlet实现网页登录功能
2021/07/04 Java/Android
GTX1650super好不好 gtx1650super显卡属于什么级别
2022/04/08 数码科技
Hive HQL支持2种查询语句风格
2022/06/25 数据库
Linux在两个服务器直接传文件的操作方法
2022/08/05 Servers