关于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 相关文章推荐
国外大牛IE版本检测!现在IE都到9了,IE检测代码
Jan 04 Javascript
js调用css属性写法
Sep 21 Javascript
js键盘上下左右键怎么触发function(实例讲解)
Dec 14 Javascript
jquery中checkbox全选失效的解决方法
Dec 26 Javascript
js数组常见操作及数组与字符串相互转化实例详解
Nov 10 Javascript
jQuery抛物线运动实现方法(附完整demo源码下载)
Jan 08 Javascript
javascript验证内容为数字以及长度为10的简单实例
Aug 20 Javascript
Bootstrap 手风琴菜单的实现代码
Jan 20 Javascript
vuejs2.0运用原生js实现简单的拖拽元素功能示例
Feb 24 Javascript
在node环境下parse Smarty模板的使用示例代码
Nov 15 Javascript
vue组件创建的三种方式小结
Feb 03 Javascript
JS前端基于canvas给图片添加水印
Nov 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为SHOPEX增加日志功能代码
2010/07/02 PHP
Thinkphp调用Image类生成缩略图的方法
2015/03/07 PHP
Javascript 不能释放内存.
2006/09/07 Javascript
javascript一些不错的函数脚本代码
2008/09/10 Javascript
js 页面传参数时 参数值含特殊字符的问题
2009/12/13 Javascript
Jquery右下角抖动、浮动 实例代码(兼容ie6、FF)
2013/08/15 Javascript
javascript随机将第一个dom中的图片添加到第二个div中示例
2013/10/08 Javascript
jQuery+PHP星级评分实现方法
2015/10/02 Javascript
jQuery form插件之ajaxForm()和ajaxSubmit()的可选参数项对象
2016/01/23 Javascript
jqPlot jQuery绘图插件的使用
2016/06/18 Javascript
初识简单却不失优雅的Vue.js
2016/09/12 Javascript
jQuery EasyUI封装简化操作
2016/09/18 Javascript
Js判断H5上下滑动方向及滑动到顶部和底部判断的示例代码
2017/11/15 Javascript
three.js如何实现3D动态文字效果
2021/03/03 Javascript
浅析Python中的getattr(),setattr(),delattr(),hasattr()
2016/06/14 Python
Python中index()和seek()的用法(详解)
2017/04/27 Python
Python使用微信SDK实现的微信支付功能示例
2017/06/30 Python
Python设计模式之观察者模式简单示例
2018/01/10 Python
django文档学习之applications使用详解
2018/01/29 Python
Python微医挂号网医生数据抓取
2019/01/24 Python
Python中typing模块与类型注解的使用方法
2019/08/05 Python
Python 字符串处理特殊空格\xc2\xa0\t\n Non-breaking space
2020/02/23 Python
在python中利用dict转json按输入顺序输出内容方式
2020/02/27 Python
python实现Pyecharts实现动态地图(Map、Geo)
2020/03/25 Python
Python实现给PDF添加水印的方法
2021/01/25 Python
英国最受欢迎的母婴精品品牌:JoJo Maman BéBé
2021/02/17 全球购物
大学生个人推荐信范文
2013/11/25 职场文书
高中生职业生涯规划书
2014/02/24 职场文书
红领巾广播站广播稿(3篇)
2014/09/20 职场文书
群众路线个人对照检查材料
2014/09/23 职场文书
2014年行政后勤工作总结
2014/12/06 职场文书
租赁协议书
2015/01/27 职场文书
幼儿园教师工作总结2015
2015/04/02 职场文书
机器人总动员观后感
2015/06/09 职场文书
background-position百分比原理详解
2021/05/08 HTML / CSS
集英社今正式宣布 成立游戏公司“集英社Games”
2022/03/31 其他游戏