关于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 基础知识 被自己遗忘的
Oct 15 Javascript
jquery 学习之一 对象访问
Nov 23 Javascript
jquery的extend和fn.extend的使用说明
Jan 09 Javascript
主页面中的两个iframe实现鼠标拖动改变其大小
Apr 16 Javascript
jquery对dom的操作常用方法整理
Jun 25 Javascript
Javascript 多物体运动的实现
Dec 24 Javascript
canvas学习之API整理笔记(二)
Dec 29 Javascript
写jQuery插件时的注意点
Feb 20 Javascript
ActiveX控件的使用-js实现打印超市小票功能代码详解
Nov 22 Javascript
在vue项目中使用md5加密的方法
Sep 14 Javascript
vue element动态渲染、移除表单并添加验证的实现
Jan 16 Javascript
深入理解Puppeteer的入门教程和实践
Mar 05 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
《Pokemon Sword·Shield》系列WEB动画《薄明之翼》第2话声优阵容公开!
2020/03/06 日漫
PHP计算加权平均数的方法
2015/07/16 PHP
使用Thinkphp框架开发移动端接口
2015/08/05 PHP
PHP基于yii框架实现生成ICO图标
2015/11/13 PHP
PHP使用fopen与file_get_contents读取文件实例分享
2016/03/04 PHP
php判断手机浏览还是web浏览,并执行相应的动作简单实例
2016/07/28 PHP
php基于curl实现随机ip地址抓取内容的方法
2016/10/11 PHP
PHP 中魔术常量的实例详解
2017/10/26 PHP
如何让您的中波更粗更长 - 中波框形天线制作
2021/03/10 无线电
百度判断手机终端并自动跳转js代码及使用实例
2014/06/11 Javascript
firefox浏览器用jquery.uploadify插件上传时报HTTP 302错误
2015/03/01 Javascript
深入浅析AngularJS和DataModel
2016/02/16 Javascript
JS获取年月日时分秒的方法分析
2016/11/28 Javascript
Bootstrap基本插件学习笔记之轮播幻灯片(23)
2016/12/08 Javascript
用vue构建多页面应用的示例代码
2017/09/20 Javascript
vue2中,根据list的id进入对应的详情页并修改title方法
2018/08/24 Javascript
webpack 3.X学习之多页面打包的方法
2018/09/04 Javascript
关于vue编译版本引入的问题的解决
2018/09/17 Javascript
Vue结合后台导入导出Excel问题详解
2019/02/19 Javascript
Vuex中实现数据状态查询与更改
2019/11/08 Javascript
详细分析vue表单数据的绑定
2020/07/20 Javascript
Django返回json数据用法示例
2016/09/18 Python
python3中str(字符串)的使用教程
2017/03/23 Python
简单实现python收发邮件功能
2018/01/05 Python
python中ASCII码字符与int之间的转换方法
2018/07/09 Python
python实现在图片上画特定大小角度矩形框
2018/10/24 Python
centos6.5安装python3.7.1之后无法使用pip的解决方案
2019/02/14 Python
使用python PIL库实现简单验证码的去噪方法步骤
2019/05/10 Python
python实现超级马里奥
2020/03/18 Python
python实现秒杀商品的微信自动提醒功能(代码详解)
2020/04/27 Python
一款利用纯css3实现的win8加载动画的实例分析
2014/12/11 HTML / CSS
HTML5的结构和语义(5):交互
2008/10/17 HTML / CSS
J2SDK1.5与J2SDK5.0有什么区别
2012/09/19 面试题
工程造价自荐信
2013/10/09 职场文书
个人简历自我评价
2014/02/02 职场文书
Nginx缓存设置案例详解
2021/09/15 Servers