关于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 相关文章推荐
jQuery Study Notes学习笔记 (二)
Aug 04 Javascript
javascript将数组插入到另一个数组中的代码
Jan 10 Javascript
Extjs Gird 支持中文拼音排序实现代码
Apr 15 Javascript
使用纯javascript实现放大镜效果
Mar 18 Javascript
Javascript实现div层渐隐效果的方法
May 30 Javascript
js实现微信分享代码
Oct 11 Javascript
三种AngularJS中获取数据源的方式
Feb 02 Javascript
JS实现图片平面旋转的方法
Mar 01 Javascript
详谈AngularJs 控制器、数据绑定、作用域
Jul 09 Javascript
微信小程序使用map组件实现解析经纬度功能示例
Jan 22 Javascript
Vue动态生成表格的行和列
Jul 18 Javascript
bootstrap table实现iview固定列的效果实例代码详解
Sep 30 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动态分页函数,PHP开发分页必备啦
2011/11/07 PHP
PHP设计模式之工厂模式定义与用法详解
2018/04/03 PHP
认识延迟时间为0的setTimeout
2008/05/16 Javascript
JavaScript 自动分号插入(JavaScript synat:auto semicolon insertion)
2009/11/04 Javascript
整理一些JavaScript的IE和火狐的兼容性注意事项
2011/03/17 Javascript
js写的方法实现上传图片之后查看大图
2014/03/05 Javascript
jQuery中index()的用法分析
2014/09/05 Javascript
Javascript window对象详解
2014/11/12 Javascript
NodeJS学习笔记之Connect中间件模块(一)
2015/01/27 NodeJs
jQuery下拉美化搜索表单效果代码分享
2015/08/25 Javascript
JS组件系列之使用HTML标签的data属性初始化JS组件
2016/09/14 Javascript
vue多级多选菜单组件开发
2020/09/08 Javascript
xmlplus组件设计系列之网格(DataGrid)(10)
2017/05/05 Javascript
使用InstantClick.js让页面提前加载200ms
2017/09/12 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
2018/09/30 Javascript
在Koa.js中实现文件上传的接口功能
2019/10/08 Javascript
bootstrap-closable-tab可实现关闭的tab标签页插件
2020/08/09 Javascript
[20:46]Ti4循环赛第三日VG vs DK
2014/07/12 DOTA
Python tkinter模块弹出窗口及传值回到主窗口操作详解
2017/07/28 Python
Python学习笔记之if语句的使用示例
2017/10/23 Python
python中hashlib模块用法示例
2017/10/30 Python
Python实现字典的遍历与排序功能示例
2017/12/23 Python
Python建立Map写Excel表实例解析
2018/01/17 Python
Python实现FTP弱口令扫描器的方法示例
2019/01/31 Python
Python二维码生成识别实例详解
2019/07/16 Python
Python列表元素常见操作简单示例
2019/10/25 Python
Python数据可视化图实现过程详解
2020/06/12 Python
美体小铺美国官网:The Body Shop美国
2017/11/10 全球购物
澳大利亚家具和家居用品在线商店:Interiors Online
2018/03/05 全球购物
英国羊绒服装购物网站:Pure Collection
2018/10/22 全球购物
大学生心理健康活动总结
2015/05/08 职场文书
2015年前台文员工作总结
2015/05/18 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
学校趣味运动会开幕词
2016/03/04 职场文书
2016年小学党支部创先争优活动总结
2016/04/05 职场文书
小学生作文写作技巧100例,非常实用!
2019/07/08 职场文书