乐趣区

Javascript实现数组去重方法及效率对比

前言

其实网上搜索这些方法一堆堆的,之所以还来写一遍主要是因为自己习惯一种之后就忘了其他方法怎么实现,就写一写总结一下,顺便做个测试看看哪个效率最高,为了更好展示效果,我会先总结认为比较好的方法,后面统一测试。(温馨提示:下文衹是为了简便,一般情况下不建议写在原型上,容易污染全局)

一,通过寻找对象属性

var ary = [14, 12, 2, 2, 2, 5, 32, 2, 59, 5, 6, 33, 12, 32, 6];
function sortFun1(ary) {var obj = {},
    i = 0,
    len = this.length;
  for (; i < len; i++) {if (!obj[this[i]]) {obj[this[i]] = 1;
      ary.push(this[i]);
    }
  }
  return ary.sort(function (a, b) {return a - b});
}
console.log(sortFun1(ary));
// [2, 2, 2, 2, 5, 5, 6, 6, 12, 12, 14, 32, 32, 33, 59]

二,通过寻找数组位置

var ary = [14, 12, 2, 2, 2, 5, 32, 2, 59, 5, 6, 33, 12, 32, 6];
function sortFun2(ary) {
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (ary.indexOf(this[i]) == -1)
      ary.push(this[i]);
  }
  return ary.sort(function (a, b) {return a - b});
}
console.log(sortFun2(ary));
// [2, 2, 2, 2, 5, 5, 6, 6, 12, 12, 14, 32, 32, 33, 59]

三,跟寻找数组位置类似,搜索数字第一次出现的位置是不是跟当前位置一样

var ary = [14, 12, 2, 2, 2, 5, 32, 2, 59, 5, 6, 33, 12, 32, 6];
function sortFun3(ary) {
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (this.indexOf(this[i]) == i)
      ary.push(this[i]);
  }
  return ary.sort(function (a, b) {return a - b});
}
console.log(sortFun3(ary));
// [2, 2, 2, 2, 5, 5, 6, 6, 12, 12, 14, 32, 32, 33, 59]

四,比较常规,先排序,再比较前后两个数字是不是相等

var ary = [14, 12, 2, 2, 2, 5, 32, 2, 59, 5, 6, 33, 12, 32, 6];
function sortFun4(ary) {ary.sort(function (a, b) {return a - b});
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (this[i] !== this[i - 1])
      ary.push(this[i]);
  }
  return ary;
}
console.log(sortFun4(ary));
// [2, 2, 2, 2, 5, 5, 6, 6, 12, 12, 14, 32, 32, 33, 59]

接下来是网上比较少的效率比较了,也是本文重点,我们先生成一个随机数组函数和计时函数统一比较
(温馨提示: 随机数组执行一次之后就保存在一个变量, 而每次执行函数花费时间都会有几毫秒偏差, 你们想看多几种结果就狠狠地按按 F5 就好了, 也只能这么搞..)

首先生成一个一千个数字的数组

function sortFun1(ary) {var obj = {},
    i = 0,
    len = this.length;
  for (; i < len; i++) {if (!obj[this[i]]) {obj[this[i]] = 1;
      ary.push(this[i]);
    }
  }
  return ary.sort(function (a, b) {return a - b});
}

function sortFun2(ary) {
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (ary.indexOf(this[i]) == -1)
      ary.push(this[i]);
  }
  return ary.sort(function (a, b) {return a - b});
}


function sortFun3(ary) {
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (this.indexOf(this[i]) == i)
      ary.push(this[i]);
  }
  return ary.sort(function (a, b) {return a - b});
}


function sortFun4(ary) {ary.sort(function (a, b) {return a - b});
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (this[i] !== this[i - 1])
      ary.push(this[i]);
  }
  return ary;
}

function randomAry(n) {var ary = [], i = 0;
  for (; i < n; i++) {ary.push(Math.ceil(Math.random() * 10000));
  }
  return ary;
}

function useTime(fn, ary) {var start = new Date();
  fn(ary);
  var end = new Date();
  console.log('本次函数运行花了:' + (end - start) + '毫秒');
}


var ary = randomAry(1000000);
useTime(sortFun1, ary);
useTime(sortFun2, ary);
useTime(sortFun3, ary);
useTime(sortFun4, ary);

本次函数运行花了:1 毫秒
本次函数运行花了:1 毫秒
本次函数运行花了:0 毫秒
本次函数运行花了:1 毫秒
(嗯,果然现代浏览器强大无比,不吐槽旧浏览器了)

看看十万个数字

function sortFun1(ary) {var obj = {},
    i = 0,
    len = this.length;
  for (; i < len; i++) {if (!obj[this[i]]) {obj[this[i]] = 1;
      ary.push(this[i]);
    }
  }
  return ary.sort(function (a, b) {return a - b});
}

function sortFun2(ary) {
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (ary.indexOf(this[i]) == -1)
      ary.push(this[i]);
  }
  return ary.sort(function (a, b) {return a - b});
}


function sortFun3(ary) {
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (this.indexOf(this[i]) == i)
      ary.push(this[i]);
  }
  return ary.sort(function (a, b) {return a - b});
}


function sortFun4(ary) {ary.sort(function (a, b) {return a - b});
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (this[i] !== this[i - 1])
      ary.push(this[i]);
  }
  return ary;
}

function randomAry(n) {var ary = [], i = 0;
  for (; i < n; i++) {ary.push(Math.ceil(Math.random() * 10000));
  }
  return ary;
}

function useTime(fn, ary) {var start = new Date();
  fn(ary);
  var end = new Date();
  console.log('本次函数运行花了:' + (end - start) + '毫秒');
}


var ary = randomAry(100000);
useTime(sortFun1, ary);
useTime(sortFun2, ary);
useTime(sortFun3, ary);
useTime(sortFun4, ary);

现在开始出现明显差距了
本次函数运行花了:65 毫秒
本次函数运行花了:4 毫秒
本次函数运行花了:4 毫秒
本次函数运行花了:5 毫秒

看看一百万个数字(数据庞大,开始吃不消了,等个五六秒吧)

function sortFun1(ary) {var obj = {},
    i = 0,
    len = this.length;
  for (; i < len; i++) {if (!obj[this[i]]) {obj[this[i]] = 1;
      ary.push(this[i]);
    }
  }
  return ary.sort(function (a, b) {return a - b});
}

function sortFun2(ary) {
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (ary.indexOf(this[i]) == -1)
      ary.push(this[i]);
  }
  return ary.sort(function (a, b) {return a - b});
}


function sortFun3(ary) {
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (this.indexOf(this[i]) == i)
      ary.push(this[i]);
  }
  return ary.sort(function (a, b) {return a - b});
}


function sortFun4(ary) {ary.sort(function (a, b) {return a - b});
  var i = 0,
    len = this.length;
  for (; i < len; i++) {if (this[i] !== this[i - 1])
      ary.push(this[i]);
  }
  return ary;
}

function randomAry(n) {var ary = [], i = 0;
  for (; i < n; i++) {ary.push(Math.ceil(Math.random() * 10000));
  }
  return ary;
}

function useTime(fn, ary) {var start = new Date();
  fn(ary);
  var end = new Date();
  console.log('本次函数运行花了:' + (end - start) + '毫秒');
}


var ary = randomAry(1000000);
useTime(sortFun1, ary);
useTime(sortFun2, ary);
useTime(sortFun3, ary);
useTime(sortFun4, ary);

本次函数运行花了:661 毫秒
本次函数运行花了:24 毫秒
本次函数运行花了:20 毫秒
本次函数运行花了:27 毫秒

总结

数据说话,

退出移动版