关于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中的事件处理
Nov 06 Javascript
js动态获取子复选项并设计全选及提交的实现方法
Jun 24 Javascript
Javascript基础学习笔记(菜鸟必看篇)
Jul 22 Javascript
理解Angular的providers给Http添加默认headers
Jul 04 Javascript
JS实现对json对象排序并删除id相同项功能示例
Apr 18 Javascript
react redux入门示例
Apr 19 Javascript
vuex进阶知识点巩固
May 20 Javascript
微信小程序中转义字符的处理方法
Mar 28 Javascript
详解微信小程序开发(项目从零开始)
Jun 06 Javascript
Vue 权限控制的两种方法(路由验证)
Aug 16 Javascript
基于vue+echarts 数据可视化大屏展示的方法示例
Mar 09 Javascript
js实现点击选项置顶动画效果
Aug 25 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利用新浪接口查询ip获取地理位置示例
2014/01/20 PHP
php封装好的人民币数值转中文大写类
2015/12/20 PHP
PHP魔术方法使用方法汇总
2016/02/14 PHP
Symfony2学习笔记之模板用法详解
2016/03/17 PHP
PHP 并发场景的几种解决方案
2019/06/14 PHP
extjs中grid中嵌入动态combobox的应用
2011/01/01 Javascript
利用JS解决ie6不支持max-width,max-height问题的方法
2014/01/02 Javascript
使用jspdf生成pdf报表
2015/07/03 Javascript
jquery点击改变class并toggle的实现代码
2016/05/15 Javascript
使用jquery如何获取时间
2016/10/13 Javascript
pc加载更多功能和移动端下拉刷新加载数据
2016/11/07 Javascript
利用node.js制作命令行工具方法教程(一)
2017/06/22 Javascript
使用原生js+canvas实现模拟心电图的实例
2017/09/20 Javascript
在vue中使用v-bind:class的选项卡方法
2018/09/27 Javascript
iview tabs 顶部导航栏和模块切换栏的示例代码
2019/03/04 Javascript
Vue项目页面跳转时浏览器窗口上方显示进度条功能
2020/03/26 Javascript
jQuery插件simplePagination的使用方法示例
2020/04/28 jQuery
解决vue-router 切换tab标签关闭时缓存问题
2020/07/22 Javascript
react的hooks的用法详解
2020/10/12 Javascript
Python selenium根据class定位页面元素的方法
2019/02/26 Python
python爬虫租房信息在地图上显示的方法
2019/05/13 Python
Python中list的交、并、差集获取方法示例
2019/08/01 Python
Python使用__new__()方法为对象分配内存及返回对象的引用示例
2019/09/20 Python
Tensorflow--取tensorf指定列的操作方式
2020/06/30 Python
智能电子秤、手表和健康监测仪:Withings(之前为诺基亚健康)
2018/10/30 全球购物
美国肌肉和力量商店:Muscle & Strength
2019/06/22 全球购物
会计与审计专业大专生求职信
2013/10/03 职场文书
中专毕业生的自我鉴定
2013/12/01 职场文书
高中语文教学反思
2014/01/16 职场文书
网络技术专业推荐信
2014/02/20 职场文书
环保小标语
2014/06/13 职场文书
党员群众路线学习心得体会
2014/11/04 职场文书
2015年社区流动人口工作总结
2015/05/12 职场文书
彻底理解golang中什么是nil
2021/04/29 Golang
Python数据分析之绘图和可视化详解
2021/06/02 Python
CSS使用Flex和Grid布局实现3D骰子
2022/08/05 HTML / CSS