关于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字符串对象toLowerCase方法入门实例(用于把字母转换为小写)
Oct 17 Javascript
限制只能输入数字的实现代码
May 16 Javascript
javascript工厂模式和构造函数模式创建对象方法解析
Dec 30 Javascript
vue-router+nginx 非根路径配置方法
Jun 30 Javascript
vue.js中toast用法及使用toast弹框的实例代码
Aug 27 Javascript
浅谈React Event实现原理
Sep 20 Javascript
使用ECharts实现状态区间图
Oct 25 Javascript
el-select 下拉框多选实现全选的实现
Aug 02 Javascript
vue的滚动条插件实现代码
Sep 07 Javascript
Vue 解决多级动态面包屑导航的问题
Nov 04 Javascript
node.js事件轮询机制原理知识点
Dec 22 Javascript
vue 使用post/get 下载导出文件操作
Aug 07 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里得到前天和昨天的日期的代码
2007/08/16 PHP
PHP 编程的 5个良好习惯
2009/02/20 PHP
php 数学运算验证码实现代码
2009/10/11 PHP
PHP源码分析之变量的存储过程分解
2014/07/03 PHP
PHP使用array_multisort对多个数组或多维数组进行排序
2014/12/16 PHP
PHP性能分析工具XHProf安装使用教程
2015/05/13 PHP
PHP连接SQL Server的方法分析【基于thinkPHP5.1框架】
2019/05/06 PHP
js 操作select和option常用代码整理
2012/12/13 Javascript
JS原型对象通俗&quot;唱法&quot;
2012/12/27 Javascript
用javascript将数据导入Excel示例代码
2014/09/10 Javascript
使用BootStrap实现表格隔行变色及hover变色并在需要时出现滚动条
2017/01/04 Javascript
axios post提交formdata的实例
2018/03/16 Javascript
原生JS实现列表子元素顺序反转的方法分析
2018/07/02 Javascript
使用js实现将后台传入的json数据放在前台显示
2018/08/06 Javascript
对angularJs中ng-style动态改变样式的实例讲解
2018/09/30 Javascript
vue读取本地的excel文件并显示在网页上方法示例
2019/05/29 Javascript
Vue CLI3基础学习之pages构建多页应用
2019/06/02 Javascript
在Python中操作日期和时间之gmtime()方法的使用
2015/05/22 Python
Python3实现的爬虫爬取数据并存入mysql数据库操作示例
2018/06/06 Python
python 读取视频,处理后,实时计算帧数fps的方法
2018/07/10 Python
用Python获取摄像头并实时控制人脸的实现示例
2019/07/11 Python
通过Django Admin+HttpRunner1.5.6实现简易接口测试平台
2020/11/11 Python
CSS3色彩模式有哪些?CSS3 HSL色彩模式的定义
2016/04/26 HTML / CSS
完美解决IE8下不兼容rgba()的问题
2017/03/31 HTML / CSS
Sunglasses Shop荷兰站:英国最大的太阳镜独立在线零售商和供应商
2017/01/08 全球购物
网页设计个人找工作求职信
2013/11/28 职场文书
学校领导班子群众路线整改措施
2014/09/16 职场文书
幼儿园见习报告
2014/10/30 职场文书
2014年消防工作总结
2014/11/21 职场文书
外贸英文求职信范文
2015/03/19 职场文书
学校中秋节活动总结
2015/03/23 职场文书
社区艾滋病宣传活动总结
2015/05/07 职场文书
2016年安全月活动总结
2016/04/06 职场文书
浅谈Mysql多表连接查询的执行细节
2021/04/24 MySQL
python实现简单聊天功能
2021/07/07 Python
Python 装饰器(decorator)常用的创建方式及解析
2022/04/24 Python