javascript实现数组去重的多种方法


Posted in Javascript onMarch 14, 2016

废话不多说,直接拿干货!

先说说这个实例的要求:写一个方法实现数组的去重。(要求:执行方法,传递一个数组,返回去重后的新数组,原数组不变,实现过程中只能用一层循环,双层嵌套循环也可写,只做参考);

先给初学者解释一下什么叫数组去重(老鸟跳过):意思就是讲数组里面重复的元素去掉,比如说var arr = [3,2,4,2,1,2]; 数组去重得到的新数组是 [3,2,4,1],就是这么一个功能。

实现方法比较简单,实现的方式也比较多,很多大牛也写过相关的文章,之所以写这边博客,旨在一是备忘,二是给初学者能更好的理解其实现的原理,好,我们看第一种实现方式:

第一种,通过遍历新数组来去重

var arr = [1,'b','b',4,3,3,4,5,1];
     
    //第一种
    Array.prototype.unique1 = function(){
      var arr1 = []; //定义一个新数组
      for(var i=0;i<this.length;i++){
        if(arr1.indexOf(this[i]) == -1){//判断目标数组中在原数组里是否存在
          arr1.push(this[i]);
        } 
      } 
      return arr1;
    }
    console.log(arr); //[1,'b','b',4,3,3,4,5,1]
    console.log(arr.unique1()); //[1, "b", 4, 3, 5]
    //这种方法的主要思路就是,新建一个数组,然后在原数组中,从第一个开始,看看新数组里面有没有这个元素,如果有,就忽略,然后进行下一个,如果没有,则把这个元素存到新数组里面,
    //也就是说,每一次比较,都会遍历新数组,直到找到相同元素为止,比较耗性能

如果大家不习惯这个写法,可以改成下面的写法,效果是一样的:

var arr = [1,'b','b',4,3,3,4,5,1];

function unique1(arr){
      var arr1 = [];
      for(var i=0;i<arr.length;i++){
        if(arr1.indexOf(arr[i]) == -1){//判断目标数组中在原数组里是否存在
          arr1.push(arr[i]); 
        } 
      } 
      return arr1;
    }
    console.log(arr); //[1,'b','b',4,3,3,4,5,1]
    console.log(unique1(arr)); //[1, "b", 4, 3, 5]

下面的方法我就不改写法了,你们可以按照上面的格式来改写一下,结果我也不输出了,因为结果是一样的,注释写在代码中,慢慢体会一下

第二种,通过hash表(这个概念有点大,具体原理就不在这里细说了,有时间我会单独写一遍,这是好东西)实现

var arr = [1,'b','b',4,3,3,4,5,1];

Array.prototype.unique2 = function(){
      var hash = {}; //定义一个hash表
      var arr1 = []; //定义一个新数组
      for(var i=0;i<this.length;i++){
        /*
          这里比较难理解,我们一步一步来看:
          hash是一个对象,则存在键值对(key:value),只不过现在是为空的,所以hash[key] = value;
          第一步:i=0;this[i]=this[0]=1; hash[this[0]] = hash[1] , 因为hash初始为空,没有找到key=1的值,所以然后undefined,
          执行下一步:hash[1] = true(此时hash对象就有了第一组键值对),将原数组的第一个数添加到新数组中,重复第一步
          因为不重复的判断hash的值都是undefined,而重复的都为true了,所以不重复都被添加到新数组中
          因为hash表存的值是存的地址,放在堆内存中,所以有多少个不重复的元素,就要分多少个内存来存放,所以这种方法比较占内存,但是相比之下,这种的运算运动是最快的,
          这也就是用空间来换取时间了,数据量比较小,推荐用此方法
        */
        if(! hash[this[i]]){
          hash[this[i]] = true;
          arr1.push(this[i]);
        }
      }
      return arr1;  
    }
    console.log(arr);
    console.log(arr.unique2());

第三种,通过遍历自身的位置是否一致来实现

var arr = [1,'b','b',4,3,3,4,5,1];

Array.prototype.unique3 = function(){
      var arr1 = []; //定义一个新数组
      for(var i=0;i<this.length;i++){
        if(this.indexOf(this[i])==i){
        //这里也是indexOf遍历,看从第一个元素在原数组中的位置,如果第一次出现的位置和下标相等,说明当前元素的不重复的,如果不等,说明该元素前面已经出现过
          arr1.push(this[i]);
        }
      }
      return arr1;  
    }
    console.log(arr);
    console.log(arr.unique3());

第四种,这个有点意思,只能运用到特殊场合,就是先跟数组排序,然后22比较,输出一个排序过的新数组

Array.prototype.unique4 = function(){
      /*
        这里是思路是,先排序(默认从小到大),然后将原数组的第一个给新数组,
        因为是经过排序的,所以重复的只会存在在相邻位置
        这里就相当于是做22比较,如果相等,则进行下一组,如果不相等,则把这个数存到新数组中,用这个数再进行比较
      */
      this.sort();
      var arr1 = [this[0]];
      for(var i=1;i<this.length;i++){
        if(this[i] !== arr1[arr1.length-1]){
          arr1.push(this[i]);
        } 
      }
      return arr1;  
    }
    console.log(arr);
    console.log(arr.unique4());

哇哈,打完收工!

要求里面还说,可以使用双层嵌套循环来实现,无法就是用2层for循环,让每一个与原数组去比较

Array.prototype.unique5 = function(){
      //双层循环,一一比较
      for(var i=0;i<this.length;i++){ //从0开始
        for(j= i+1;j<this.length;j++){ //从1开始,逐个比较
          if(this[i] === this[j]){ //如果恒定
            this.splice(j,1);  //就将这个元素删掉
          } 
        } 
      }
      return this;  
    }
    console.log(arr);
    console.log(arr.unique5());

这种写法的循环次数太多,不推荐,有人会说,第一种和第三种不也是每次都遍历一遍吗?跟第5种感觉也差不多呢?是的,你能这么理解,说明你理解了,但是呢,又不是特别的理解,我们说差不多那可就差太多了,indexOf()表示的是找到第一个匹配的元素就会

停止遍历,而第5种则是不管找不找得到,都会把整个数组遍历一遍,如果数据量大,那你觉得哪个性能要好一点?

特别注意的一点:如果在比较两两之间的值是全等或不等的时候,一定要用恒定(===)和不恒定(!==),因为这会涉及到元素的类型上,如 1与'1'是不恒等的!

上面的可真是干货了,一点水分都没有,只能靠大家自己领悟了!

Javascript 相关文章推荐
Javascript(AJAX)解析XML的代码(兼容FIREFOX/IE)
Jul 11 Javascript
通过复制Table生成word和excel的javascript代码
Jan 20 Javascript
JavaScript阻止事件冒泡示例分享
Dec 28 Javascript
深入理解JavaScript系列(45):代码复用模式(避免篇)详解
Mar 04 Javascript
JS给Textarea文本框添加行号的方法
Aug 20 Javascript
JQuery对ASP.NET MVC数据进行更新删除
Jul 13 Javascript
angularjs+bootstrap实现自定义分页的实例代码
Jun 19 Javascript
微信小程序 开发MAP(地图)实例详解
Jun 27 Javascript
微信小程序实现订单倒计时
Nov 01 Javascript
vue-路由精讲 二级路由和三级路由的作用
Aug 06 Javascript
js+css3实现炫酷时钟
Aug 18 Javascript
微信小程序picker组件两列关联使用方式
Oct 27 Javascript
javascript实现PC网页里的拖拽效果
Mar 14 #Javascript
Jquery实现简单的轮播效果(代码管用)
Mar 14 #Javascript
node模块机制与异步处理详解
Mar 13 #Javascript
JS中创建函数的三种方式及区别
Mar 13 #Javascript
使用jQuery操作HTML的table表格的实例解析
Mar 13 #Javascript
Javascript数组Array方法解读
Mar 13 #Javascript
GitHub上一些实用的JavaScript的文件压缩解压缩库推荐
Mar 13 #Javascript
You might like
超人钢铁侠联手合作?美漫作家呼吁DC漫威合作联动以抵抗疫情
2020/04/09 欧美动漫
PHP中使用register_shutdown_function函数截获fatal error示例
2015/04/21 PHP
php+MySql实现登录系统与输出浏览者信息功能
2016/07/01 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
JavaScript的类型简单说明
2010/09/03 Javascript
js操作textarea方法集合封装(兼容IE,firefox)
2011/02/22 Javascript
express的中间件bodyParser详解
2014/12/04 Javascript
JavaScript匿名函数用法分析
2015/02/13 Javascript
NodeJS使用jQuery选择器操作DOM
2015/02/13 NodeJs
jQuery插件开发的五种形态小结
2015/03/04 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
2015/03/13 Javascript
javascript框架设计之类工厂
2015/06/23 Javascript
浅谈js中调用函数时加不加括号的问题
2016/07/28 Javascript
import与export在node.js中的使用详解
2017/09/28 Javascript
通过vue-router懒加载解决首次加载时资源过多导致的速度缓慢问题
2018/04/08 Javascript
JavaScript去掉数组重复项的方法分析【测试可用】
2018/07/19 Javascript
vue-cli3 DllPlugin 提取公用库的方法
2019/04/24 Javascript
超轻量级的js时间库miment使用解析
2019/08/02 Javascript
layui-table对返回的数据进行转变显示的实例
2019/09/04 Javascript
Python中优化NumPy包使用性能的教程
2015/04/23 Python
Saltstack快速入门简单汇总
2016/03/01 Python
python 实现分页显示从es中获取的数据方法
2018/12/26 Python
实例介绍Python中整型
2019/02/11 Python
Python进度条的制作代码实例
2019/08/31 Python
python 输出列表元素实例(以空格/逗号为分隔符)
2019/12/25 Python
详解Python中的分支和循环结构
2020/02/11 Python
css3背景_动力节点Java学院整理
2017/07/11 HTML / CSS
Sofmap官网:日本著名的数码电器专卖店
2017/05/19 全球购物
经验丰富大学生村干部自我鉴定
2014/01/22 职场文书
《理想》教学反思
2014/02/17 职场文书
学员自我鉴定
2014/03/19 职场文书
消防宣传口号
2014/06/16 职场文书
联谊会开场白
2015/06/01 职场文书
四十年同学聚会致辞
2015/07/28 职场文书
有关保护环境的宣传标语100条
2019/08/07 职场文书
CSS的calc函数用法小结
2022/06/25 HTML / CSS