Javascript中的去重

之前看知呼中的一个问题,觉得自己需要整理一下: 知呼连接https://www.zhihu.com/question/29558082

先生成array:

var arr = [], num = 0;
  for (var i = 0; i < 10000; i++) {
    num = i%4;
    if(num == 0) {
      arr.push(Math.floor(Math.random() * 99999));
    } else if(num == 1){
      arr.push(function(){
        var some = Math.random();
      });
    } else if(num == 2){
      arr.push({
        a:Math.random()
      });
    } else if(num == 3) {
      arr.push(`${Math.floor(Math.random() * 99999)}`);
    }
  }

第一个方法是 玉伯 的去重方法,利用Object的key唯一的特性进行对比:

function uniq1 (arr){
    var hash = {}, ret = [];

    for(let item of arr) {
      if(!hash[item]) {
        hash[item] = true;
        ret.push(item);
      }
    }

    return ret;
  }

第二种和第三种是ES6出来以后,利用Set的特性,和数组不同,一个Set不会包含相同元素

function uniq2 (arr) {
    return Array.from(new Set(arr))
  }

  function uniq3 (arr) {
    const seen = new Map()
    return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
  }

第四种方法是通过去掉当前的,然后判断是否前面包含相同元素:

  function uniq4 (array) {
    for (var i = array.length; i--;) {
      var n = array[i]
          // 先排除 即 如果它是清白的 后面就没有等值元素
      array.splice(i, 1, null)
      if (~array.indexOf(n)) {
          array.splice(i, 1); //不清白
      } else {
          array.splice(i, 1, n); //清白
      }
    }
  }

通过跑的时间对比性能:

  (function(){
    let arrays = [];
    for(let i = 0; i < 100; i++) {
      arrays.push(Object.assign([], arr));
    }

    var date = new Date();
    for(let i = 0; i < 100; i++) {
      uniq1(arrays[i]);
    }
    console.log('uniq1: ', (new Date() - date)/100.00);

    var date = new Date();
    for(let i = 0; i < 100; i++) {
      uniq2(arrays[i]);
    }
    console.log('uniq2: ', (new Date() - date)/100.00);

    var date = new Date();
    for(let i = 0; i < 100; i++) {
      uniq3(arrays[i]);
    }
    console.log('uniq3: ', (new Date() - date)/100.00);

    var date = new Date();
    for(let i = 0; i < 100; i++) {
      uniq4(arrays[i]);
    }
    console.log('uniq4: ', (new Date() - date)/100.00);
  })();

跑分结果:


 

小结:

    可以发现前三种方法时间都差不多,用Set的两种稍微快一些。

    不过uniq1的去重方法适合各种浏览器的使用,不需要考虑Babel翻译。

    而Set是ES6的新功能,需要考虑IE11以下的兼容性问题,但是明显Set的数据存储结构专门为一种操作作了速度优化, 所以运行速度上面有一些优势。

    至于第四种方法,比较前三种明显的时间多出很多,我在运行100遍循环的时候,会感觉明显的卡顿,主要原因还是因为splice方法的时间消耗巨大。好处也显而易见,适合各种浏览器的同时,是在原有array上直接修改,没有创建任何多余的空间。

猜你喜欢

转载自clarkfbar.iteye.com/blog/2334635