关于js数组去重的问题小结


Posted in Javascript onJanuary 24, 2014

1.根据js对象中key不重复的原则,构思出数组去重的方法,按照最常规的思维如下:

function distinctArray(arr){
var obj={},temp=[];
for(var i=0;i<arr.length;i++){
if(!obj[arr[i]]){
temp.push(arr[i]);
obj[arr[i]] =true;
}
}
return temp;
   }
   var testarr=[1,2,3,2];
   console.log(distinctArray(testarr));// [1,2,3]

看起来还不错的样子哦,但是如果变成一下情况:
var testarr1=[1,2,3,"2"];
console.log(distinctArray(testarr));// [1,2,3]
竟然还是一样的结果,这就并非我们想要的了,我们需要的结果应该是[1,2,3,"2"].即去重的过程中需要保证类型的完整性。

针对以上情况,我们对上述方法进行改进:

function distinctArrayImprove(arr){
var obj={},temp=[];
for(var i=0;i<arr.length;i++){
if(!obj[typeof (arr[i])+arr[i]]){
temp.push(arr[i]);
obj[typeof (arr[i])+arr[i]] =true;
}
}
return temp;
}

以上方法在向对象中放key的时候加了typeof的前缀,那么让我们看看效果吧。
var testarr1=[1,2,3,"2"];
console.log(distinctArray(testarr));// [1,2,3,"2"]
哎呦,不错哦!那么是不是这个函数就彻底ok呢,让我们再看一种情况!
var testarr1=[1,2,3,"2",{a:1},{b:1}];
console.log(distinctArray(testarr));// [1,2,3,"2",{a:1}]
竟然出现这个结果,怎么把{b:1}给莫名其妙的删掉了呢,去重的过程中如果出现误删除有用的数据可是很严重的问题,所以以上方法也不是perfect的一种,那就让我们接着往下看吧。

2.在1中我们的主要思想是利用js对象中key不重复的理念来指导我们的思维,但是最终没有解决所有的问题,那么接着我们可以考虑换一种思维模式来实现我们想要的功能。

用slice和splice方法来实现数组的去重,如下:

function distinctArray2(arr){
var temp=arr.slice(0);//数组复制一份到temp
for(var i=0;i<temp.length;i++){
for(j=i+1;j<temp.length;j++){
if(temp[j]==temp[i]){
temp.splice(j,1);//删除该元素
j--;
}
}
}
return temp;
}

测试:
var testarr1=[1,2,3,"2"];
console.log(distinctArray(testarr));// [1,2,3]
var testarr2=[1,2,2,{a:1},{a:1},{a:1,b:2},function(){alert("b");},function(){alert("b");}];
//[1,2,{a:1},{a:1},{a:1,b:2},function(){alert("b");},function(){alert("b");}]

测试结果仍然不能满足我们的需求,肿么办?经过我们队以上方法的研究,我们发现主要的问题出在比较两个对象相等的操作上,distinctArray2中利用”==“来比较,并不能区分大对象的内容是否相等,鉴于此种情况,我们另外写了一个方法:

function distinctArrayAll(arr){
var isEqual=function(obj1,obj2){
//两个对象地址相等,必相等
if(obj1===obj2){
return true;
}
if(typeof(obj1)==typeof(obj2)){
if(typeof(obj1)=="object"&&typeof(obj2)=="object"){
var pcount=0;
for(var p in obj1){
pcount++;
if(!isEqual(obj1[p],obj2[p])){
return false;
}
}
for(var p in obj2){
pcount--;
}
return pcount==0;
}else if(typeof(obj1)=="function"&&typeof(obj2)=="function"){
if(obj1.toString()!=obj2.toString()){
return false;
}
}else {
if(obj1!=obj2){
return false;
}
}
}else{
return false;
}
return true;
}
var temp=arr.slice(0);//数组复制一份到temp
for(var i=0;i<temp.length;i++){
for(j=i+1;j<temp.length;j++){
if(isEqual(temp[j],temp[i])){
temp.splice(j,1);//删除该元素
j--;
}
}
}
return temp;
}

测试:
var testArr3=[1,2,2,{a:1},{a:1},{a:1,b:2},function(){alert("b");},function(){alert("b");}];
console.log(distinctArrayAll(testArr3));
//结果 [1,2,{a:1},{a:1,b:2},function(){alert("b");}]

哎呀,终于顺利完成去重的任务了,至于每个方法的性能问题,我们留待下一次讨论!我们可以看出最后一种方法是万能去重法,可以针对复杂数组来去重,但是相应的执行开销也是相当大的,在实际的项目开发中有时我们需要的可能仅仅是纯数字或者纯字符串的去重,这就要求我们根据需求灵活选用相应的算法,不求太perfect,只求在满足需求的基础上使程序效率更高!

Javascript 相关文章推荐
extjs之去除s.gif的影响
Dec 25 Javascript
javaScript如何处理从java后台返回的list
Apr 24 Javascript
js实现编辑div节点名称的方法
Dec 17 Javascript
JavaScript的面向对象编程基础
Aug 13 Javascript
javascript实现C语言经典程序题
Nov 29 Javascript
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
Dec 10 Javascript
详解Bootstrap创建表单的三种格式(一)
Jan 04 Javascript
jQuery ajax时间差导致的变量赋值问题分析
Jan 22 Javascript
js判断主流浏览器类型和版本号的简单实现代码
May 26 Javascript
JavaScript实现数值自动增加动画
Dec 28 Javascript
VUE前后端学习tab写法实例
Aug 06 Javascript
教你部署vue项目到docker
Apr 05 Vue.js
js数组去重的常用方法总结
Jan 24 #Javascript
JQuery的$和其它JS发生冲突的快速解决方法
Jan 24 #Javascript
js判断60秒以及倒计时示例代码
Jan 24 #Javascript
innerText 使用示例
Jan 23 #Javascript
登陆成功后自动计算秒数执行跳转
Jan 23 #Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
Jan 23 #Javascript
html dom节点操作(获取/修改/添加或删除)
Jan 23 #Javascript
You might like
给初学PHP的5个入手程序
2006/11/23 PHP
PHP实现的交通银行网银在线支付接口ECSHOP插件和使用例子
2014/05/10 PHP
yii2中添加验证码的实现方法
2016/01/09 PHP
PHP strip_tags保留多个HTML标签的方法
2016/05/22 PHP
Yii2.0框架模型添加/修改/删除数据操作示例
2019/07/18 PHP
jquery选择器-根据多个属性选择示例代码
2013/10/21 Javascript
简介JavaScript中strike()方法的使用
2015/06/08 Javascript
深入解析JavaScript中的arguments对象
2016/06/12 Javascript
浅谈jQuery效果函数
2016/09/16 Javascript
Zabbix添加Node.js监控的方法
2016/10/20 Javascript
微信小程序使用navigateTo数据传递的实例
2017/09/26 Javascript
vue、react等单页面项目应该这样子部署到服务器
2018/01/03 Javascript
vue 左滑删除功能的示例代码
2019/01/28 Javascript
vue-froala-wysiwyg 富文本编辑器功能
2019/09/19 Javascript
如何在vue项目中嵌入jsp页面的方法(2种)
2020/02/06 Javascript
vue实现日历表格(element-ui)
2020/09/24 Javascript
通过实例解析javascript Date对象属性及方法
2020/11/04 Javascript
在阿里云服务器上配置CentOS+Nginx+Python+Flask环境
2016/06/18 Python
Python正则表达式知识汇总
2017/09/22 Python
Python设计模式之观察者模式简单示例
2018/01/10 Python
Python3.8中使用f-strings调试
2019/05/22 Python
Django Rest framework权限的详细用法
2019/07/25 Python
python GUI库图形界面开发之pyinstaller打包python程序为exe安装文件
2020/02/26 Python
pandas使用函数批量处理数据(map、apply、applymap)
2020/11/27 Python
HTML5为输入框添加语音输入功能的实现方法
2017/02/06 HTML / CSS
乌克兰网上服装店:Bolf.ua
2018/10/30 全球购物
企业宣传标语
2014/06/09 职场文书
亚运会口号
2014/06/20 职场文书
工作说明书格式
2014/07/29 职场文书
高速铁道技术专业求职信
2014/08/09 职场文书
产品委托授权书范本
2014/09/16 职场文书
2015年五四青年节活动总结
2015/02/10 职场文书
《黄山奇石》教学反思
2016/02/18 职场文书
提取视频中的音频 Python只需要三行代码!
2021/05/10 Python
Python中OpenCV实现查找轮廓的实例
2021/06/08 Python
Java实现超大Excel文件解析(XSSF,SXSSF,easyExcel)
2022/07/15 Java/Android