indexOf去重

Array.prototype.unique1 = function() {

var arr = [];

for (var i = 0; i < this.length; i++) {

var item = this[i];

if (arr.indexOf(item) === -1) {

arr.push(item);

}

}

return arr;

}

[1,2,3,'4',3,4,3,1,'34',2].unique1(); //[1, 2, 3, "4", 4, "34"]

不过,在 IE6-8 下,数组的 indexOf 方法还不存在(虽然这已经算有点古老的话题了O(∩_∩)O~),但是,程序员就要写一个indexOf方法:

var indexOf = [].indexOf ? function(arr, item) {

return arr.indexOf(item);

} :

function indexOf(arr, item) {

for (var i = 0; i < arr.length; i++) {

if (arr[i] === item) {

return i;

}

}

return -1;

}

Array.prototype.unique2 = function() {

var arr = [];

for (var i = 0; i < this.length; i++) {

var item = this[i];

if (arr.indexOf(item) === -1) {

arr.push(item);

}

}

return arr;

}

[1,2,3,'4',3,4,3,1,'34',2].unique2(); //[1, 2, 3, "4", 4, "34"]

indexOf还可以以这样的去重思路:

Array.prototype.unique3 = function(){

var arr = [this[0]];

for(var i = 1; i < this.length; i++)

{

if (this.indexOf(this[i]) == i){

arr.push(this[i]);

}

}

return arr;

}

[1,2,3,'4',3,4,3,1,'34',2].unique3(); //[1, 2, 3, "4", 4, "34"]

hash去重

以上indexOf正确性没问题,但性能上,两重循环会降低性能。那我们就用hash。

Array.prototype.unique4 =
function() {

var arr =
[];

var hash =
{};

for (var i =
0; i < this.length; i++) {

var
item = this[i];

var
key = typeof(item) + item

if (hash[key]
!== 1) {

arr.push(item);

hash[key] = 1;

}

}

return arr;

}

[1,2,3,'4',3,4,3,1,'34',2].unique4();
//[1, 2, 3, "4", 4, "34"]

核心是构建了一个 hash 对象来替代 indexOf。空间换时间。注意在 JavaScript 里,对象的键值只能是字符串(当然,ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的Hash结构现。),因此需要var key = typeof(item) + item 来区分数值 1 和字符串 '1' 等情况。

那如果你想要'4' 和 4 被认为是相同的话(其他方法同理)

Array.prototype.unique5 =
function(){

var arr=[];

var hash={};

for(var
i=0,len=this.length;i<len;i++){

if(!hash[this[i]]){

arr.push(this[i]);

hash[this[i]]=true;

}

}

return arr;

}

[1,2,3,'4',3,4,3,1,'34',2].unique5();
//[1, 2, 3, "4", "34"]

排序后去重

Array.prototype.unique6 =
function(){

this.sort();

var arr =
[this[0]];

for(var i = 1; i
< this.length; i++){

if(
this[i] !== arr[arr.length-1]){

arr.push(this[i]);

}

}

return arr;

}

[1,2,3,'4',3,4,3,1,'34',2].unique6();
//[1, 2, 3, "34", "4", 4]

先把数组排序,然后比较相邻的两个值,排序的时候用的JS原生的sort方法,所以非常快。而这个方法的缺陷只有一点,比较字符时按照字符编码的顺序进行排序。所以会看到10排在2前面这种情况。不过在去重中不影响。不过,解决sort的这个问题,是sort方法接受一个参数,这个参数是一个方法:

function compare(value1,value2) {

if (value1 <
value2) {

return -1;

} else if (value1
> value2) {

return 1;

} else {

return 0;

}

}

[1,2,5,2,10,3,20].sort(compare);
 //[1, 2, 2, 3, 5, 10, 20]

Set去重

ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。现在浏览器正在全面支持,服务端的node也已经支持。

Array.prototype.unique7 =
function(){

return
Array.from(new Set(this));

}

[1,2,3,'4',3,4,3,1,'34',2].unique7();
//[1, 2, 3, "4", 4, "34"]

方法库

推荐一个方法库Underscore.js,在node或浏览器js中都很受欢迎。

const _ = require('underscore');

_.uniq([1, 2, 1, 3, 1, 4]);
 //[1, 2, 3, 4]

测试时间

以上方法均可以用一个简单的方法去测试一下所耗费的时间,然后对各个方法做比较择优:

console.time("test");

[1,2,3,'4',3,4,3,1,'34',2].unique7();

console.timeEnd("test");

==> VM314:3 test: 0.378ms

让数据变得大一点,就随机创建100万个数:

var arr = [];

var num = 0;

for(var i = 0; i < 1000000;
i++){

num =
Math.floor(Math.random()*100);

arr.push(num);

}

console.time("test");

arr.unique7();

console.timeEnd("test");

JavaScript-数组去重由慢到快由繁到简的更多相关文章

  1. 160819、JavaScript-数组去重由慢到快由繁到简

    JavaScript-数组去重由慢到快由繁到简演化   indexOf去重 Array.prototype.unique1 = function() { var arr = []; for (var ...

  2. JavaScript数组去重方法及测试结果

    最近看到一些人的去面试web前端,都说碰到过问JavaScript数组去重的问题,我也学习了一下做下总结. 实际上最有代表性也就三种方法:数组双重循环,对象哈希,排序后去重. 这三种方法我都做了性能测 ...

  3. JavaScript 数组去重方法总结

    1.遍历数组法: 这应该是最简单的去重方法(实现思路:新建一新数组,遍历数组,值不在新数组就加入该新数组中) // 遍历数组去重法 function unique(arr){ var _arr = [ ...

  4. 也谈面试必备问题之 JavaScript 数组去重

    Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...

  5. javascript数组去重算法-----3

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. javascript数组去重算法-----2

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. javascript数组去重算法-----1

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. javascript数组去重算法-----5

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. javascript数组去重算法-----4(另一种写法__2)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. javascript中函数的3个高级技巧

    × 目录 [1]作用域安全 [2]惰性载入 [3]函数绑定 前面的话 函数对任何一门语言来说都是一个核心的概念,在javascript中更是如此.前面曾以深入理解函数系列的形式介绍了函数的相关内容,本 ...

  2. Web APi之EntityFramework【CRUD】(三)

    前言 之前我们系统学习了EntityFramework,个人觉得有些东西不能学了就算完了,必须要学以致用,在Web API上也少不了增(C).删(D).改(U).查(R).鉴于此,我们通过EF来实现W ...

  3. Rust初步(三):使用atom搭配racer进行rust编程

    在rust.cc社区中有一个关于rust编辑器的讨论(话说很多人要学一个新语言,都会立即考虑编辑器的问题,包括我在内),主要关注的是,智能提示(这个真的太重要了).大家讨论下来有几个选择 1. ecl ...

  4. pixi.js教程中文版--基础篇

    前言 Pixi.js使用WebGL,是一个超快的HTML5 2D渲染引擎.作为一个Javascript的2D渲染器,Pixi.js的目标是提供一个快速的.轻量级而且是兼任所有设备的2D库.提供无缝 C ...

  5. PC网站CSS分享

    这里想总结些编写网页的经验,以PC端的为主,前面总结过后台的,今天写些前台的,参考了bootstrap3.3.5.bootstrip2.3.2和模版matrix. 前段时间还写过一篇<前端基础学 ...

  6. JS详细教程(下)

    五.数组 数组是数据的有序列表,每个元素在数组中都有数字位置编号,也就是索引.JS中的数组是弱类型,每一项都可以保存任何类型的数据. 创建数组 ①使用Array构造函数 var arr=new Arr ...

  7. Oracle 数据库重放(Database Replay)功能演示

    我们可以捕获生产环境的工作量,在测试环境上重放,从而在不影响生产环境的前提下做一些改动测试. 捕获:需要Oracle版本为10.2.0.4或更高. 重放:需要Oracle版本为11g Release ...

  8. 1Z0-053 争议题目解析481

    1Z0-053 争议题目解析481 考试科目:1Z0-053 题库版本:V13.02 题库中原题为: 481.Which statement is true about a running sessi ...

  9. MySQL入门03-MySQL配置安全性、易用性

    一.设定管理员用户和密码 二.处理test库权限隐患 三.自定义脚本提升易用性 中间定义文件 启动MySQL服务 关闭MySQL服务 快捷登录MySQL 四.设置开机自动启动MySQL服务 Refer ...

  10. Jackson的简单用法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1简介 Jackson具有比较高的序列化和反序列化效率,据测试,无论是 ...