关于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 相关文章推荐
NiftyCube——轻松实现圆角边框
Feb 20 Javascript
jQuery结合AJAX之在页面滚动时从服务器加载数据
Jun 30 Javascript
JavaScript学习笔记之创建对象
Mar 25 Javascript
js+html5实现canvas绘制网页时钟的方法
May 21 Javascript
详解如何将angular-ui的图片轮播组件封装成一个指令
May 09 Javascript
Node调用Java的示例代码
Sep 20 Javascript
jQuery的Ajax接收java返回数据方法
Aug 11 jQuery
原生JS实现的简单小钟表功能示例
Aug 30 Javascript
web页面和微信小程序页面实现瀑布流效果
Sep 26 Javascript
webpack优化的深入理解
Dec 10 Javascript
在微信小程序中使用vant的方法
Jun 07 Javascript
javascript设计模式 ? 代理模式原理与用法实例分析
Apr 16 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
基于mysql的论坛(1)
2006/10/09 PHP
Banner程序
2006/10/09 PHP
PHP中的float类型使用说明
2010/07/27 PHP
php简单图像创建入门实例
2015/06/10 PHP
图片自动更新(说明)
2006/10/02 Javascript
JS解析XML的实现代码
2009/11/12 Javascript
Javascript学习笔记8 用JSON做原型
2010/01/11 Javascript
无缝滚动js代码通俗易懂(自写)
2013/06/19 Javascript
JS操作数据库的实例代码
2013/10/17 Javascript
jQuery Mobile的loading对话框显示/隐藏方法分享
2013/11/26 Javascript
Jquery Uploadify上传带进度条的简单实例
2014/02/12 Javascript
关于jQuery中的each方法(jQuery到底干了什么)
2014/03/05 Javascript
Javascript进制转换实例分析
2015/05/14 Javascript
基于Javascript实现弹出页面效果
2016/01/01 Javascript
JavaScript语言精粹经典实例(整理篇)
2016/06/07 Javascript
jQuery实现页面点击后退弹出提示框的方法
2016/08/24 Javascript
轻松掌握JavaScript代理模式
2016/08/26 Javascript
js放大镜放大购物图片效果
2017/01/18 Javascript
Vue.use源码分析
2017/04/22 Javascript
vue 组件高级用法实例详解
2018/04/11 Javascript
vue实现图书管理系统
2020/12/29 Vue.js
[07:20]2014DOTA2西雅图国际邀请赛 选手讲解积分赛第二天
2014/07/11 DOTA
Python 利用内置set函数对字符串和列表进行去重的方法
2018/06/29 Python
Python get获取页面cookie代码实例
2018/09/12 Python
Django如何自定义分页
2018/09/25 Python
django 使用全局搜索功能的实例详解
2019/07/18 Python
python腾讯语音合成实现过程解析
2019/08/01 Python
pytorch中使用cuda扩展的实现示例
2020/02/12 Python
python实现logistic分类算法代码
2020/02/28 Python
Python semaphore evevt生产者消费者模型原理解析
2020/03/18 Python
丝芙兰新加坡官网:Sephora新加坡
2018/12/04 全球购物
男方婚礼答谢词
2015/01/20 职场文书
银行优秀员工推荐信
2015/03/24 职场文书
优秀团员主要事迹材料
2015/11/05 职场文书
为什么说餐饮很难做,是因为你不了解这些新规则
2019/08/20 职场文书
go 原生http web 服务跨域restful api的写法介绍
2021/04/27 Golang