关于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实现Java的List功能(实例讲解)
Nov 07 Javascript
一个js导致的jquery失效问题的解决方法
Nov 27 Javascript
js设置文本框中焦点位置在最后的示例代码(简单实用)
Mar 04 Javascript
javascript常用函数归纳整理
Oct 31 Javascript
使用AngularJS创建自定义的过滤器的方法
Jun 18 Javascript
jQuery表单对象属性过滤选择器实例详解
Sep 13 Javascript
JS用斜率判断鼠标进入DIV四个方向的方法
Nov 07 Javascript
支持移动端原生js轮播图
Feb 16 Javascript
利用node.js写一个爬取知乎妹纸图的小爬虫
May 03 Javascript
jQuery简单绑定单个事件的方法示例
Jun 10 jQuery
使用JSON格式提交数据到服务端的实例代码
Apr 01 Javascript
Mac下安装vue
Apr 11 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
php xml 入门学习资料
2011/01/01 PHP
PHP之密码加密的几种方式
2015/07/29 PHP
zend framework重定向方法小结
2016/05/28 PHP
workerman结合laravel开发在线聊天应用的示例代码
2018/10/30 PHP
关于图片验证码设计的思考
2007/01/29 Javascript
JAVASCRIPT实现的WEB页面跳转以及页面间传值方法
2010/05/13 Javascript
js关闭子窗体刷新父窗体实现方法
2012/12/04 Javascript
js写一个字符串转成驼峰的实例
2013/06/21 Javascript
js 为label标签和div标签赋值的方法
2013/08/08 Javascript
Jquery中给animation加更多的运作效果实例
2013/09/05 Javascript
变量声明时命名与变量作为对象属性时命名的区别解析
2013/12/06 Javascript
深入理解JavaScript系列(38):设计模式之职责链模式详解
2015/03/04 Javascript
每天一篇javascript学习小结(Array数组)
2015/11/11 Javascript
基于JS实现PHP的sprintf函数实例
2015/11/14 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
2016/10/30 Javascript
js 中获取制定的cook信息实现方法
2016/11/19 Javascript
Vue实现自带的过滤器实例
2017/03/09 Javascript
JS传播事件、取消事件默认行为、阻止事件传播详解
2017/08/14 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
2018/04/18 Javascript
解决jQuery使用append添加的元素事件无效的问题
2018/08/30 jQuery
Vue移动端右滑屏幕返回上一页附源码下载
2019/06/26 Javascript
基于vue和websocket的多人在线聊天室
2020/02/01 Javascript
python基础教程之基本内置数据类型介绍
2014/02/20 Python
详解Django中的过滤器
2015/07/16 Python
对matplotlib改变colorbar位置和方向的方法详解
2018/12/13 Python
Java byte数组操纵方式代码实例解析
2020/07/22 Python
class类在python中获取金融数据的实例方法
2020/12/10 Python
HTML5之WebGL 3D概述(下)—借助类库开发及框架介绍
2013/01/31 HTML / CSS
求职简历推荐信范文
2013/12/02 职场文书
初中生物教学反思
2014/01/10 职场文书
2015年银行柜员工作总结报告
2015/04/01 职场文书
土建技术员岗位职责
2015/04/11 职场文书
退休教师追悼词
2015/06/23 职场文书
有关花店创业的计划书模板
2019/08/27 职场文书
python代码实现扫码关注公众号登录的实战
2021/11/01 Python
Python+OpenCV实现图片中的圆形检测
2022/04/07 Python