Js数组去重方法及效率对比

更新日期: 2019-06-30 阅读: 2.5k 标签: 数组

前言

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


一,通过寻找对象属性

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毫秒


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/4421

相关推荐

indexOf的三种使用方法

indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。这里基本用法大家一般都清楚,一般在实际工作中常与数组的方法合用来对数组进行一些操作

关于Vue不能监听(watch)数组变化

vue无法监听数组变化的情况,但是数组在下面两种情况下无法监听:利用索引直接设置数组项时,例如arr[indexofitem]=newValue;修改数组的长度时,例如arr.length=newLength

JS计算两个数组的交集、差集、并集、补集(多种实现方式)

使用 ES5 语法来实现虽然会麻烦些,但兼容性最好,不用考虑浏览器 JavaScript 版本,使用 ES5 语法来实现虽然会麻烦些,但兼容性最好,不用考虑浏览器 JavaScript 版本。也不用引入其他第三方库。

js数组中改变元素的位置:互换,置顶,上移,下移

unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。splice() 方法可删除从 index 处开始的零个或多个元素

js使用数组+循环+条件实现数字转换为汉字的简单方法。

单个数字转汉字的解决方法:利用数组存储0-9的汉字、 ary.length和str.length不用多说,这是指ary数组和str字符串的长度。这里我们需要注意的是str.charAt(j)和ary[i],分别指在str这个字符串中索引为j的元素,在ary中索引为i的元素。

Js遍历数组时注意 Empty Item 的影响

这两天碰到个问题:从日志中发现一些来自 iOS 10.3 的报错「Cannot read property \\\'xxx\\\' of undefined」,定位到代码的报错位置,发现是遍历某数组时产生的报错,该数组的元素应该全都是 Object,但实际上出现了异常的元素

JS数组扁平化(flat)方法总结

需求:多维数组=>一维数组 ;flat和flatMap方法为ES2019(ES10)方法,目前还未在所有浏览器完全兼容。第四种处理:用 reduce 实现数组的 flat 方法

数组、字符串去重

今天说的数组和字符串去重呢,主要用到es6新的数据结构 Set,它类似于数组,但是成员的值都是唯一的,没有重复的值,所以活用Set来进行数组和字符串的去重。

Js数组中所有方法(超详细)

concat()把元素衔接到数组中。 every() 方法使用指定函数检测数组中的所有元素:filter()返回满足断言函数的数组元素。forEach()为数组的每一个元素调用指定函数。

[译]async-await 数组循环的几个坑

在 Javascript 循环中使用 async/ await 循环遍历数组似乎很简单,但是在将两者结合使用时需要注意一些非直观的行为。让我们看看三个不同的例子,看看你应该注意什么,以及哪个循环最适合特定用例。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!