数组去重方法分析

时间:2021-04-25 20:43:12

方法一

通过新数组的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());

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

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表法,其余两种什么鬼啊....

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

        当数组长度纬度较大时,6-7s是什么鬼...9-10秒又是什么鬼...还要不要愉快的玩耍了... 先睡一觉?

 

简单分析了一下:

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

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

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

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

 

 

差点忘了ES6实现数组去重...明天写!