关于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 相关文章推荐
测试JavaScript字符串处理性能的代码
Dec 07 Javascript
JavaScript 利用Cookie记录用户登录信息
Dec 08 Javascript
JQuery中each()的使用方法说明
Aug 19 Javascript
23个Javascript弹出窗口特效整理
Feb 25 Javascript
JAVA四种基本排序方法实例总结
Jul 24 Javascript
jQuery实例—选项卡的简单实现(js源码和jQuery)
Jun 14 Javascript
express+mockjs实现模拟后台数据发送功能
Jan 07 Javascript
JS和Canvas实现图片的预览压缩和上传功能
Mar 30 Javascript
Vue 全局loading组件实例详解
May 29 Javascript
在JavaScript中如何访问暂未存在的嵌套对象
Jun 18 Javascript
layer.open的自适应及居中及子页面标题的修改方法
Sep 05 Javascript
Vue+Java+Base64实现条码解析的示例
Sep 23 Javascript
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
迅雷下载《中学科技》怀旧期刊下载
2021/02/27 无线电
php 遍历数据表数据并列表横向排列的代码
2009/09/05 PHP
PHP之数组学习
2011/05/29 PHP
php学习之function的用法
2012/07/14 PHP
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
2013/06/03 PHP
一个图片地址分解程序(用于PHP小偷程序)
2014/08/23 PHP
PHP中Session和Cookie是如何操作的
2015/10/10 PHP
老司机传授Ubuntu下Apache+PHP+MySQL环境搭建攻略
2016/03/20 PHP
php格式化json函数示例代码
2016/05/12 PHP
Yii2.0中使用js异步删除示例
2017/03/10 PHP
Nginx下ThinkPHP5的配置方法详解
2017/08/01 PHP
表格单元格交错着色实现思路及代码
2013/04/01 Javascript
JSP跨iframe如何传递参数实现代码
2013/09/21 Javascript
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
2014/06/10 Javascript
浅析location.href跨窗口调用函数
2016/11/22 Javascript
underscore之function_动力节点Java学院整理
2017/07/11 Javascript
基于jQuery实现无缝轮播与左右点击效果
2018/05/13 jQuery
微信小程序车牌号码模拟键盘输入功能的实现代码
2018/11/11 Javascript
24个解决实际问题的ES6代码片段(小结)
2020/02/02 Javascript
JavaScript 面向对象程序设计详解【类的创建、实例对象、构造函数、原型等】
2020/05/12 Javascript
node运行js获得输出的三种方式示例详解
2020/07/02 Javascript
Python入门学习之字符串与比较运算符
2015/10/12 Python
Python基础中所出现的异常报错总结
2016/11/19 Python
Python通过for循环理解迭代器和生成器实例详解
2019/02/16 Python
这可能是最好玩的python GUI入门实例(推荐)
2019/07/19 Python
一行Python代码制作动态二维码的实现
2019/09/09 Python
Django 实现Admin自动填充当前用户的示例代码
2019/11/18 Python
Python压缩模块zipfile实现原理及用法解析
2020/08/14 Python
详解HTML5 canvas绘图基本使用方法
2018/01/29 HTML / CSS
日本订房网站,预订日本星级酒店/温泉旅馆:Relux(支持中文)
2020/01/03 全球购物
HR喜欢的自荐信格式
2013/10/08 职场文书
岳庙导游词
2015/02/04 职场文书
中学生国庆节演讲稿2015
2015/07/30 职场文书
Python中threading库实现线程锁与释放锁
2021/05/17 Python
Win11应用商店打开闪退怎么解决? win11应用商店打不开的多种解决办法
2022/04/05 数码科技
MySQL 自动填充 create_time 和 update_time
2022/05/20 MySQL