关于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遍历input取得input的name
Apr 27 Javascript
javascript 正则替换 replace(regExp, function)用法
May 22 Javascript
JavaScript 和 Java 的区别浅析
Jul 31 Javascript
用Jquery实现滚动新闻
Feb 12 Javascript
高性能JavaScript模板引擎实现原理详解
Feb 05 Javascript
详解Javacript和AngularJS中的Promises
Feb 09 Javascript
解决vue-cli webpack打包后加载资源的路径问题
Sep 25 Javascript
优雅地使用loading(推荐)
Apr 20 Javascript
Vue组件通信的几种实现方法
Apr 25 Javascript
JavaScript函数式编程(Functional Programming)组合函数(Composition)用法分析
May 22 Javascript
CKeditor富文本编辑器使用技巧之添加自定义插件的方法
Jun 14 Javascript
vuex分模块后,实现获取state的值
Jul 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
Terran兵种介绍
2020/03/14 星际争霸
mysql时区问题
2008/03/26 PHP
php auth_http类库进行身份效验
2009/03/19 PHP
PHP中文件上传的一个问题
2010/09/04 PHP
PHP学习笔记之一
2011/01/17 PHP
php _autoload自动加载类与机制分析
2012/02/10 PHP
PHP 使用memcached简单示例分享
2015/03/05 PHP
PHP Cookie学习笔记
2016/08/23 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
PHP中一个有趣的preg_replace函数详解
2018/08/15 PHP
Javascript四舍五入Math.round()与Math.pow()使用介绍
2013/12/27 Javascript
nodejs实例解析(输出hello world)
2017/01/03 NodeJs
Vue中保存用户登录状态实例代码
2017/06/07 Javascript
angularjs使用div模拟textarea文本框的方法
2018/10/02 Javascript
详解vue移动端项目代码拆分记录
2019/03/15 Javascript
vue+php实现的微博留言功能示例
2019/03/16 Javascript
JS函数动态传递参数的方法分析【基于arguments对象】
2019/06/05 Javascript
vue实现的多页面项目如何优化打包的步骤详解
2020/07/19 Javascript
vue keep-alive实现多组件嵌套中个别组件存活不销毁的操作
2020/10/30 Javascript
[49:13]DOTA2上海特级锦标赛C组资格赛#1 OG VS LGD第一局
2016/02/27 DOTA
python pickle 和 shelve模块的用法
2013/09/16 Python
python使用pil生成图片验证码的方法
2015/05/08 Python
Python文件夹与文件的相关操作(推荐)
2016/07/25 Python
基于python中staticmethod和classmethod的区别(详解)
2017/10/24 Python
Python排序搜索基本算法之插入排序实例分析
2017/12/11 Python
Python中的TCP socket写法示例
2018/05/11 Python
分享8个非常流行的 Python 可视化工具包
2019/06/05 Python
python爬虫之快速对js内容进行破解
2019/07/09 Python
Python简单实现词云图代码及步骤解析
2020/06/04 Python
BONIA波尼亚新加坡官网:皮革手袋,鞋类和配件
2016/08/25 全球购物
英国鹦鹉店:Parrot Essentials
2018/12/03 全球购物
LACOSTE波兰官网:Polo衫、服装和鞋类
2020/09/29 全球购物
酒店端午节活动方案
2014/08/26 职场文书
2014报到证办理个人委托书
2014/10/08 职场文书
2014年就业工作总结
2014/11/26 职场文书
Java实现HTML转为Word的示例代码
2022/06/28 Java/Android