zoukankan      html  css  js  c++  java
  • 数组去重方法分析

    数组去重方法分析

    方法一、通过新数组的indexOf方法

     1 Array.prototype.unique = Array.prototype.unique || function () {
     2     var result = [];
     3     this.forEach(function (v) {
     4         if(result.indexOf(v) < 0){
     5             //result.indexOf(v) >= 0 表示这个 v 已经在数组result[]里面了
     6             // < 0 则表示这个 v 还没在数组里面 没有的才push   有的就不push了  所以不会出现两个相等的 v 。
     7             result.push(v);
     8         }
     9     });
    10     return result;
    11 };

    方法二、通过原数组的indexOf方法

     1 Array.prototype.unique = Array.prototype.unique || function () {
     2         var result = [];
     3         for(var i = 0; i <this.length; i++) {
     4             if (this.indexOf(this[i]) == i) {
     5                 //this.indexOf(this[i]) !== i 表面这个元素已经出现过了  == i表示第一次出现,这时才push到result里面去。
     6                 result.push(this[i]);
     7             }
     8         }
     9         return result;
    10     };

    方法三、使用hash表

     1 Array.prototype.unique = Array.prototype.unique || function () {
     2         var hash = {}; //新建一个hash表
     3         var result = []; //新建一个数组
     4         for (var i = 0; i <this.length; i++){
     5             if(!hash[this[i]]){  //如果hash表中没有这项
     6                 hash[this[i]] = true;  //就把这项添加到hash表中去
     7                 result.push(this[i]);  //并且把这项添加到新数组
     8             }
     9         }
    10         return result;
    11     };

            为了检验三种方法性能的优劣,我写了一个测试程序 ,这里我创建 一个长度为len的数组,数组的每一项为0 - wth的随机数组,给len和wth赋不同值,再在network里面看他们各自执行时间。

    1     var len = 1000, wth = 1000;
    2     var arr = new Array(len);
    3     for(var i = 0; i < wth; i++){
    4         arr[i] = Math.floor(Math.random()*wth);
    5     }
    6     console.log(arr.unique());

            检验数组长度和纬度不同时三种方法的效率(chrome浏览器下),结果如下:

    1、当 len =1000, wth = 1000时

            三种方法执行时间基本一样,都在30ms左右;

    2、设置 len = 1000, wth = 10000时

           三种方法执行时间按顺序分别为:100ms左右、120ms左右、38ms左右;

    3、设置len =  10000, wth = 10000时

           此时测试出来的时间与第二种设置基本一样! 

    4、设置len  =100000,wth = 10000时

           三种方法执行时间按顺序分别为:120ms左右、9~10s之间、60ms左右;

    5、设置len = 100000,wth = 100000时

          三种方法执行时间分别为:6-7s之间、9~10s之间、60ms左右

    数据很明显:时间上最稳定的方式是第三种--hash表法,其余两种什么鬼啊....

           当数组长度纬度较小时,用indexOf方法种方法勉强完成任务,性能劣与hash表法,其中方法一优于方法二;

           当数组长度纬度较大时,6-7s是什么鬼...9-10秒又是什么鬼...这个时候这两种方法都只有gg。。。

    简单分析一下:

          第一二中方法用到了数组的indexOf方法,这种方法会寻找参数再数组中第一次出现的位置,很显然,js引擎在实现这个方法是会遍历数组直到找到目标为止,

          所以这种方法会消耗很多时间。

          第三种方法用的是hash表,把已经出现过的通过下标的形式存入一个Object内,而下标的引用要比用indexOf搜索数组快很多!当然,这种方法也不是完美的,

          因为多了一个hash表,内存占用更多,相当于用空间换时间。。

    方法四、Set结构法

          ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

          Set 本身是一个构造函数,用来生成 Set 数据结构。看看下面的代码。

    1     const s = new Set();
    2     [1,3,2,3,6,7,2].forEach(x => s.add(x));
    3     console.log(s);
    4     //{1,3,2,6,7}

          运行结果是{1,3,2,6,7},很显然这不是一个数组。要将它转化为一个数组,那再看看下面的方法。

    1  const set = new Set([1,2,3,2,5]);
    2     const array = Array.from(set);
    3     console.log(array);
    4     //[1,2,3,5]

          这里用到了Array的from方法,其实还可以封装一个利用set结构转数组的方法,如下:

    1     function derepetition(array){
    2         return Array.from(new Set(array));
    3     }
    4     console.log(derepetition([1,3,2,3,5]));
    5     //[1,3,2,5]

          其实还有更简便的方法...

    1     const set1 = new Set([1,2,3,3,5]);
    2     [...set1];  //[1,2,3,5]

          这里就简直不讲道理了,不过是真心的简便!!!!

  • 相关阅读:
    jQuery里的$.ajax()方法详解
    express框架使用axios进行post请求, 两次请求问题
    electron-vue 报错 Unresolved node modules: bufferutil, utf-8-validate, canvas
    electron-vue离线打包
    个推技术:性能提升60%↑ 成本降低50%↓ Spark性能调优看这篇就够了!
    百亿级日志流分析实践 | 剖析个推后效分析功能实现原理
    iOS开发常用国外网站清单
    一篇文章搞定Git——Git代码管理及使用规范
    音视频技术入门——音频处理
    Java内存空间知识点梳理
  • 原文地址:https://www.cnblogs.com/cdut007/p/7360283.html
Copyright © 2011-2022 走看看