关于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 相关文章推荐
用Div仿showModalDialog模式菜单的效果的代码
Mar 05 Javascript
关于IE浏览器以及Firefox下的javascript冒泡事件的响应层级
Oct 14 Javascript
创建公共调用 jQuery Ajax 带返回值
Aug 01 Javascript
js添加table的行和列 具体实现方法
Jul 22 Javascript
js中apply方法的使用详细解析
Nov 04 Javascript
js控制元素显示在屏幕固定位置及监听屏幕高度变化的方法
Aug 11 Javascript
JavaScript实现带缓冲效果的随屏滚动漂浮广告代码
Nov 06 Javascript
基于JavaScript实现快速转换文本语言(繁体中文和简体中文)
Mar 07 Javascript
JavaScript实战(原生range和自定义特效)简单实例
Aug 21 Javascript
js实现日历的简单算法
Jan 24 Javascript
Webpack 服务器端代码打包的示例代码
Sep 19 Javascript
JavaScript中var的重要性实例分析
Jul 09 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实现登录验证码校验功能
2018/05/17 PHP
PHP实现发送微博消息功能完整示例
2019/12/04 PHP
JavaScript 面向对象之命名空间
2010/05/04 Javascript
jquery实现居中弹出层代码
2010/08/25 Javascript
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
阻止子元素继承父元素事件具体思路及实现
2013/05/02 Javascript
javascript实现促销倒计时+fixed固定在底部
2013/09/18 Javascript
javascript为下拉列表动态添加数据项
2014/05/23 Javascript
javascript实现禁止右键和F12查看源代码
2014/12/26 Javascript
JavaScript页面模板库handlebars的简单用法
2015/03/02 Javascript
微信小程序 UI布局常用技巧整理总结
2016/12/05 Javascript
jquery 键盘事件的使用方法详解
2017/09/13 jQuery
Angular之toDoList的实现代码示例
2017/12/02 Javascript
Angular 封装并发布组件的方法示例
2018/04/19 Javascript
利用JavaScript的Map提升性能的方法详解
2019/08/14 Javascript
p5.js绘制旋转的正方形
2019/10/23 Javascript
js实现div色块碰撞
2020/01/16 Javascript
python脚本爬取字体文件的实现方法
2017/04/29 Python
用Python实现大文本文件切割的方法
2019/01/12 Python
python将print输出的信息保留到日志文件中
2019/09/27 Python
简单了解python中的f.b.u.r函数
2019/11/02 Python
浅析Python 责任链设计模式
2020/09/11 Python
python中实现栈的三种方法
2020/12/19 Python
CSS3 文字动画效果
2020/11/12 HTML / CSS
HTML5的结构和语义(5):内嵌媒体
2008/10/17 HTML / CSS
HTML5 的新的表单元素(datalist/keygen/output)使用介绍
2013/07/19 HTML / CSS
阿迪达斯西班牙官方网站:adidas西班牙
2016/07/21 全球购物
世界知名接发和假发品牌:Poze Hair
2017/03/08 全球购物
阿联酋航空官方网站:Emirates
2017/10/17 全球购物
自我鉴定注意事项
2014/01/19 职场文书
时尚休闲吧创业计划书
2014/01/25 职场文书
城市规划应届毕业生自荐信
2014/07/04 职场文书
居委会个人对照检查材料思想汇报
2014/09/29 职场文书
总经理助理岗位职责范本
2015/03/31 职场文书
《观察物体》教学反思
2016/02/17 职场文书
详细介绍python操作RabbitMq
2022/04/12 Python