关于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 弹出层注册页面等(asp.net后台)
Jun 17 Javascript
JS实现程序暂停与继续功能代码解读
Oct 10 Javascript
关于javascript事件响应的基础语法总结(必看篇)
Dec 26 Javascript
详解AngularJS验证、过滤器、指令
Jan 04 Javascript
JavaScript异步上传图片文件的实例代码
Jul 04 Javascript
vue+ElementUI实现订单页动态添加产品数据效果实例代码
Jul 13 Javascript
webpack打包node.js后端项目的方法
Mar 10 Javascript
微信小程序自定义组件的实现方法及自定义组件与页面间的数据传递问题
Oct 09 Javascript
Vue解析带html标签的字符串为dom的实例
Nov 13 Javascript
ES6使用 Array.includes 处理多重条件用法实例分析
Mar 02 Javascript
Vue 修改网站图标的方法
Dec 31 Vue.js
详解Vue中$props、$attrs和$listeners的使用方法
Feb 18 Vue.js
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
我的论坛源代码(六)
2006/10/09 PHP
一个简单的网页密码登陆php代码
2012/07/17 PHP
codeigniter框架批量插入数据
2014/01/09 PHP
php使用function_exists判断函数可用的方法
2014/11/19 PHP
thinkphp修改配置进入默认首页的方法
2017/02/07 PHP
PHP根据树的前序遍历和中序遍历构造树并输出后序遍历的方法
2017/11/10 PHP
在Laravel 中实现是否关注的示例
2019/10/22 PHP
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
2012/08/14 Javascript
JQuery给元素添加/删除节点比如select
2013/04/02 Javascript
jQuery查询数据返回object和字符串影响原因是什么
2013/08/09 Javascript
让网页跳转到指定位置的jquery代码非书签
2013/09/06 Javascript
jquery图形密码实现方法
2015/03/11 Javascript
JS组件Bootstrap导航条使用方法详解
2016/04/29 Javascript
浅析js绑定事件的常用方法
2016/05/15 Javascript
js数组的五种迭代方法及两种归并方法(推荐)
2016/06/14 Javascript
总结几道关于Node.js的面试问题
2017/01/11 Javascript
老生常谈jacascript DOM节点获取
2017/04/17 Javascript
Vue.js简易安装和快速入门(第二课)
2017/10/17 Javascript
关于微信小程序bug记录与解决方法
2018/08/15 Javascript
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
vue 计算属性和侦听器的使用小结
2021/01/25 Vue.js
Python编程实现双击更新所有已安装python模块的方法
2017/06/05 Python
基于python调用jenkins-cli实现快速发布
2020/08/14 Python
Expedia马来西亚旅游网站:廉价酒店,度假村和航班预订
2016/07/26 全球购物
Auchan Direct波兰:欧尚在线杂货店
2016/10/19 全球购物
小蚁科技官方商店:YI Technology
2019/08/23 全球购物
类如何去实现接口
2013/12/19 面试题
请写出一段Python代码实现删除一个list里面的重复元素
2015/12/29 面试题
实习生个人的自我评价
2013/12/08 职场文书
推广普通话演讲稿
2014/05/23 职场文书
寒山寺导游词
2015/02/03 职场文书
小学元宵节活动总结
2015/02/06 职场文书
学生会个人总结范文
2015/02/15 职场文书
2015年酒店客房部工作总结
2015/04/25 职场文书
创业计划书之外语培训班
2019/11/02 职场文书
MySQL5.7并行复制原理及实现
2021/06/03 MySQL