详解javascript数组去重问题


Posted in Javascript onNovember 06, 2015

首先,我想到的是另建一个结果数组,用来存储原始数组中不重复的数据。遍历原始数组依次跟结果数组中的元素进行比较,检测是否重复。于是乎,我写出了如下代码A

Array.prototype.clearRepetitionA = function(){
   var result = [];
   var isRepetition;
   for(var i=0; i<this.length; i++){
     isRepetition = false;
     for(var j=0; j<result.length; j++){
       if(this[i] === result[j]){
         isRepetition = true;
         break;
       }
     }
     if(!isRepetition){
       result.push(this[i]);
     }
   }
   return result;
 }

写完之后,忽然想起来前几天刚看的ECMAScript 5中的数组方法indexOf 可以检索数组元素。于是我又使用indexOf 方法替代了第二层循环,写出了如下代码B

Array.prototype.clearRepetitionB = function(){
   var result = [];
   for(var i=0; i<this.length; i++){
     if(result.indexOf(this[i]) == -1){
       result.push(this[i]);
     }
   }
   return result;
 }

代码一下子从17行变成了9行了,简洁多了。高三数学大题解法一般都不止一种的啊,然后我就继续再想其他方法了。indexOf 方法的意思是搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引,没有找到就返回 -1 ,第一个参数就是要搜索的值,第二个参数可选:它指定数组中的一个索引,从那里开始搜索,如果省略这个参数,则从头搜索。思维一发散,想到了前面方法都是检测值是否重复的,现在有了indexOf 方法不就可以根据检测到的每个元素的第一次出现时的索引和这个元素自身的索引值比较相等来判断是否重复嘛。所以,我又写出了代码C:

Array.prototype.clearRepetitionC = function(){
   var result = [this[0]];
   for(var i=1; i<this.length; i++){
     if(this.indexOf(this[i]) == i){
       result.push(this[i]);
     }
   }
   return result;
 }

写完这个,又继续想了想,实在是想不出其他方法了,这三个方法都是很基础的方法。于是,我就去对照答案,检验自己了。一看答案,发现自己还是真实太弱了,简单的问题还是有些奇思妙想的。下面不是自己想的了,就不再说太多我的心路历程了。废话不多说,直接上经典的答案+解析了。
首先,先说一个算法中经常说的以空间换时间的解法,保持队形,我们就叫它代码D吧:

Array.prototype.clearRepetitionD = function(){
   var result = [];
   var obj = {};
   var key,type;
   for(var i=0; i<this.length; i++){
     key = this[i];
     type = typeof key;
     if(!obj[key]){
       obj[key] = [type];
       result.push(key);
     }else if(obj[key].indexOf(type)){
       obj[key].push(type);
       result.push(key);
     }
   }
   return result;
 }

这个方法中在遍历原始数组时用一个对象 obj 的属性来保存原始数组中元素的值。同时这个属性的值是一个数组,用来存储这个属性的类型,这一点可以把原始数组中类似数字1元素和字符串‘1'的元素区分开。这个方法通过额外构建一个对象的方式降低了上面三种方法中indexOf方法所花费的时间,可以说较为高效吧。
如果你已经满足于上面所说的以空间换时间的高效方法而不继续看下去的话,那就大错特错了,好戏总在后头嘛。现在好戏开场,毫无疑问,就是代码E了:

Array.prototype.clearRepetitionE = function(){
   var result = [];
   for(var i=0; i<this.length; i++){
     for(var j=i+1; j<this.length; j++){
       if(this[i] === this[j]){
         j = ++i;
       }
     }
     result.push(this[i]);
   }
   return result;
 }

代码D以空间换时间,感觉也就一般般。那么代码E呢?这代码是错误的吧,这个真的能去重吗?是的,起初我都没看懂这代码,看了解析后又看了一遍之后才明白过来。那么,没看懂的看官也要认真的看解析了:第一层从前往后遍历原始数组,第二层循环是检测每个元素是否跟它之后的元素重复,如果它之后有重复元素则跳过它;如果这个元素之后所有元素都跟他不重复了,则把它添加到结果数组中。这个方法实现思路就是:获取无重复的最右一值添加到结果数组中,这个跟第一种方法相比也优化了第二层的循环,效率要比它高,不过这个方法的结果数组中元素的顺序跟原始数组中元素的顺序不一样了。

看完了代码E解析的你是不是已经伸出了大拇指、投放出了敬佩的目光呢?(这些鲜花和荣誉别给我,应该给写这个方法的大神去)。下面再说最后一个方法:那就是先排序,再去重。老规矩,它叫代码F

Array.prototype.clearRepetitionF = function(){
   this.sort();
   var result = [this[0]];
   for(var i=1; i<this.length; i++){
     if(this[i] !== result[result.length-1]){
       result.push(this[i]);
     }
   }
   return result;
 }

这个先用数组的排序方法sort进行数组元素排序,然后再进行去重工作。

以上就是对javascript数组去重问题的一步步研究,不断改进代码,总共分享了六段代码,希望大家认真学习,能够有所收获。

Javascript 相关文章推荐
js函数的延迟加载实现代码
Oct 11 Javascript
简介可以自动完成UI的AngularJS工具angular-smarty
Jun 23 Javascript
jQuery实现的自定义弹出层效果实例详解
Sep 04 Javascript
无阻塞加载js,防止因js加载不了影响页面显示的问题
Dec 18 Javascript
JS中关于正则的巧妙操作
Aug 31 Javascript
全面介绍vue 全家桶和项目实例
Dec 27 Javascript
20行JS代码实现粘贴板复制功能
Feb 06 Javascript
vue2.0 + element UI 中 el-table 数据导出Excel的方法
Mar 02 Javascript
关于layui 实现点击按钮添加一行(方法渲染创建的table)
Sep 29 Javascript
JS apply用法总结和使用场景实例分析
Mar 14 Javascript
JavaScript通如何过RGraph实现动态仪表盘
Oct 15 Javascript
关于JavaScript回调函数的深入理解
Jun 27 Javascript
基于JavaScript实现仿京东图片轮播效果
Nov 06 #Javascript
实现非常简单的js双向数据绑定
Nov 06 #Javascript
浅析javascript中的事件代理
Nov 06 #Javascript
详解javascript中的事件处理
Nov 06 #Javascript
jQuery插件实现静态HTML验证码校验
Nov 06 #Javascript
jQuery Real Person验证码插件防止表单自动提交
Nov 06 #Javascript
jQuery实现非常实用漂亮的select下拉菜单选择效果
Nov 06 #Javascript
You might like
php的list()的一步操作给一组变量进行赋值的使用
2011/05/18 PHP
浅谈PHP的反射机制
2016/12/15 PHP
微信公众平台开发教程⑤ 微信扫码支付模式介绍
2019/04/10 PHP
新手入门常用代码集锦
2007/01/11 Javascript
JavaScript 原型继承之构造函数继承
2011/08/26 Javascript
JavaScript面向对象知识串结(读JavaScript高级程序设计(第三版))
2012/07/17 Javascript
file控件选择上传文件确定后触发的js事件是哪个
2014/03/17 Javascript
document.write的几点使用心得
2014/05/14 Javascript
jquery.ajax之beforeSend方法使用介绍
2014/12/08 Javascript
浅谈jquery高级方法描述与应用
2016/10/04 Javascript
如何提高数据访问速度
2016/12/26 Javascript
ajax的分页查询示例(不刷新页面)
2017/01/11 Javascript
nodejs6下使用koa2框架实例
2017/05/18 NodeJs
jQuery 控制文本框自动缩小字体填充
2017/06/16 jQuery
Vue2.5通过json文件读取数据的方法
2018/02/27 Javascript
vue项目中api接口管理总结
2018/04/20 Javascript
详解 Python 读写XML文件的实例
2017/08/02 Python
TensorFlow深度学习之卷积神经网络CNN
2018/03/09 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
2020/06/09 Python
2021年的Python 时间轴和即将推出的功能详解
2020/07/27 Python
使用PyCharm官方中文语言包汉化PyCharm
2020/11/18 Python
canvas 实现 github404动态效果的示例代码
2017/11/15 HTML / CSS
香港卓悦化妆品官网:BONJOUR
2017/09/21 全球购物
英国最大的在线床超市:Bed Star
2019/01/24 全球购物
印尼在线旅游门户网站:NusaTrip
2019/11/01 全球购物
实习求职信
2013/12/01 职场文书
机关工会开展学习雷锋活动总结
2014/03/01 职场文书
责任书格式范文
2014/07/28 职场文书
2014派出所所长群众路线对照检查材料思想汇报
2014/09/18 职场文书
光棍节联谊晚会活动策划书
2014/10/10 职场文书
高中生逃课检讨书
2014/10/10 职场文书
幼儿园毕业典礼园长致辞
2015/07/29 职场文书
丧事酒宴答谢词
2015/09/30 职场文书
pdf论文中python画的图Type 3 fonts字体不兼容的解决方案
2021/04/24 Python
对PyTorch中inplace字段的全面理解
2021/05/22 Python
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL