关于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 写类方式之十
Jul 05 Javascript
js的压缩及jquery压缩探讨(提高页面加载性能/保护劳动成果)
Jan 29 Javascript
js中top/parent/frame概述及案例应用
Feb 06 Javascript
window.location.href的用法(动态输出跳转)
Aug 09 Javascript
jQuery中 prop() attr()使用详解
May 19 Javascript
js删除局部变量的实现方法
Jun 25 Javascript
JQuery查找子元素find()和遍历集合each的方法总结
Mar 07 Javascript
jQuery中layer分页器的使用
Mar 13 Javascript
vue实现element-ui对话框可拖拽功能
Aug 17 Javascript
JQuery获取可视区尺寸和文档尺寸及制作悬浮菜单示例
May 14 jQuery
在mpvue框架中使用Vant WeappUI组件库的注意事项【推进】
Jun 09 Javascript
vue用BMap百度地图实现即时搜索功能
Sep 26 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 中的类
2006/10/09 PHP
php 什么是PEAR?(第二篇)
2009/03/19 PHP
PHP include_path设置技巧分享
2011/07/03 PHP
php中获取主机名、协议及IP地址的方法
2014/11/18 PHP
详解php用curl调用接口方法,get和post两种方式
2017/01/13 PHP
Jquery倒数计时按钮setTimeout的实例代码
2013/07/04 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
JavaScript事件委托用法分析
2015/01/24 Javascript
javascript数组去重的方法汇总
2015/04/14 Javascript
js精美的幻灯片画集特效代码分享
2015/08/29 Javascript
jquery实现倒计时功能
2015/12/28 Javascript
Bootstrap页面缩小变形的快速解决办法
2017/02/03 Javascript
整理关于Bootstrap警示框的慕课笔记
2017/03/29 Javascript
详解用node编写自己的cli工具
2017/05/23 Javascript
jQuery中的类名选择器(.class)用法简单示例
2018/05/14 jQuery
vue+iview动态渲染表格详解
2019/03/19 Javascript
微信小程序如何使用云开发
2019/05/17 Javascript
了解重排与重绘
2019/05/29 Javascript
[01:34]传奇从这开始 2016国际邀请赛中国区预选赛震撼开启
2016/06/26 DOTA
python简单文本处理的方法
2015/07/10 Python
轻松掌握python设计模式之访问者模式
2016/11/18 Python
Python学习小技巧之列表项的推导式与过滤操作
2017/05/20 Python
pandas.dataframe按行索引表达式选取方法
2018/10/30 Python
Python3爬虫学习之应对网站反爬虫机制的方法分析
2018/12/12 Python
关于Django ForeignKey 反向查询中filter和_set的效率对比详解
2018/12/15 Python
Python 通过打码平台实现验证码的实现
2019/05/13 Python
分享8个非常流行的 Python 可视化工具包
2019/06/05 Python
python GUI库图形界面开发之PyQt5时间控件QTimer详细使用方法与实例
2020/02/26 Python
Python实现RabbitMQ6种消息模型的示例代码
2020/03/30 Python
python3中的logging记录日志实现过程及封装成类的操作
2020/05/12 Python
Html5应用程序缓存(Cache manifest)
2018/06/04 HTML / CSS
Pure Collection美国官网:来自英国羊绒专家的奢华羊绒
2017/11/19 全球购物
数百万免费的图形资源:Freepik
2020/09/21 全球购物
小学教育毕业生自荐信
2013/11/18 职场文书
羽毛球比赛策划方案
2014/06/13 职场文书
工程资料员岗位职责
2015/04/13 职场文书