资讯专栏INFORMATION COLUMN

JavaScript数组去重总结

shmily / 2479人阅读

摘要:需求给定一个数组,里面有重复的数字,字符串,或者是二维的数组对象等,将里面的重复的去除,并返回新数组针对数字及字符串的方法测试数组为方法一思路用两个循环,相互比较然后去掉重复的数字。

声明:
本文给出的大多数方法都不是原创,在具体方法使用时给出了出处的链接,不过有部分方法实现较简单很多地方都有,所以未注明,在最后会给出所有的参考链接。文章来自个人博客, 转载请注明出处。

需求:

给定一个数组,里面有重复的数字,字符串,或者是二维的数组、对象等,将里面的重复的去除,并返回新数组

针对数字及字符串的方法

测试数组为: var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];

方法一
思路:用两个for循环,相互比较然后去掉重复的数字。
实现:

var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
var uniqArray1 = function(arr) {
    var uniqArr = [];
    var arrLen = arr.length;
    for(var i = 0; i < arrLen; i++) {
          for(var j = i + 1; j < arrLen; j++) {
              if(arr[i] == arr[j]) {
                  j = ++i;
              }
        }
          uniqArr.push(arr[i]);
    }
      return uniqArr;
};
console.log(uniqArray1(arr));
//[ 7, "1", "3", "5" ]

方法一容易想到,但是当测试数据很多时,由于双重循环会导致性能很差。

方法二
思路:新建数组,遍历原数组,检测当新数组中不存在原数组中的元素时将其push进去,最后返回新数组
实现:

var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
var uniqArray2 = function(arr) {
    var newArr = [];
    for(var i = 0,arrLen = arr.length; i < arrLen; i++) {
        //indexOf在IE8一下不支持
        if(newArr.indexOf(arr[i]) == -1) {   
            newArr.push(arr[i]);
        }
    }
    return newArr;
};
console.log(uniqArray2(arr));
//[ 1, 7, "1", 3, 5, "3", "5" ]

比方法一的性能好一些,但是对于需要考虑IE6-8的,需要额外再加点代码:

//该代码来自:http://www.cnblogs.com/wteam-xq/p/4732351.html
//判断浏览器是否支持indexOf ,indexOf 为ecmaScript5新方法 IE8以下(包括IE8, IE8只支持部分ecma5)不支持
if (!Array.prototype.indexOf){
  // 新增indexOf方法
  Array.prototype.indexOf = function(item){
    var result = -1, a_item = null;
    if (this.length == 0){
      return result;
    }
    for(var i = 0, len = this.length; i < len; i++){
      a_item = this[i];
      if (a_item === item){
        result = i;
        break;
      }  
    }
    return result;
  }
}

方法三
思路:利用sort方法排序,然后比较数组中前后两个数字是否相同,去掉不相同的返回新数组
实现:

var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
var uniqArray3 = function(arr) {
    arr.sort();
    var newArr = [arr[0]];
    for(var i = 1, arrLen = arr.length; i < arrLen; i++) {
        if( arr[i] != newArr[newArr.length- 1]) {
            newArr.push(arr[i]);
        }
    }
    return newArr;
};
console.log(uniqArray3(arr));
//[ 1, 3, 5, 7 ]

一个关于sort方法的小插曲:

关于sort方法需要补充一点,如果需要利用sort进行升序或降序排列,为了实现排序,
sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串确定如何排序,例如:

var values = [1,10,5,65,666,223];
values.sort();
console.log(values);
//[ 1, 10, 223, 5, 65, 666 ]

即使数组中每一项都是数值,sort()比较的也是字符串,而在比较字符串时"10"位于"5"前面,于是数组的顺序就不是预期的了。
sort可以接受一个比较函数,进而达到我们预期的比较结果:

function compare(a , b) {
    if( a < b) {
        return -1;
    }else if(a>b) {
        return 1;
    }else {
        return 0;
    }
}
var values = [1,10,5,65,666,223];
values.sort(compare);
console.log(values);
//[ 1, 5, 10, 65, 223, 666 ]

这样就得到了升序排列,而想要降序时,只需要在打印时reverse()一下即可。

方法四
思路:利用对象中是否有一样的属性进行比较。
实现:

//from:http://blog.jobbole.com/33099/
var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
var uniqArray4 = function(arr) {
    var result = [];
    var hash = {};    
    var item,key;
    for(var i = 0, arrLen = arr.length; i < arrLen; i++) {
        item = arr[i];
        //对象的键值只能是字符串,
        key = typeof(item) + item;   //区分数值 1 和字符串 "1" 等情况
        if(!hash[key]) {  
              result.push(item);  //hash用来反射key是否重复
              hash[key] = true;   //表明该值存进新数组了
        }
    }
    return result;
};
console.log(uniqArray4(arr));
//[ 1, 7, "1", 3, 5, "3", "5" ]

方法五
思路:利用对象字面量的key和value关联性,
实现:

//from: https://segmentfault.com/q/1010000000262609
var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
var uniqArray5 = function(arr) {
    var obj = {};
    var len = arr.length;
    for(var i = 0; i < len; i++) {
       obj[arr[i]] = arr[i];
    }
    return Object.keys(obj);
};
console.log(uniqArray5(arr));
//[ "1", "3", "5", "7" ]

方法六
思路:利用数组的filter方法
实现:

//from: https://segmentfault.com/q/1010000003864059
var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
var uniqArray6 = function(arr) {
    return arr.filter(function (elem, index) {
        return arr.indexOf(elem) === index;
    });
};
console.log(uniqArray6(arr));
//[ 1, 7, "1", 3, 5, "3", "5" ]

对于filter()方法的补充:
filter: 对数组中的每一个元素调用参数中指定的过滤函数,并将对于过滤函数返回值为true的那些数组元素集合为新的数组返回。

方法七
思路:利用数组的filter方法

var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
  var uniqArray8 = arr.filter(function(element, index,array) {
        return array.indexOf(element) >= index;
    });
console.log(uniqArray8);
//[ 1, 7, "1", 3, 5, "3", "5" ]

方法八
思路:利用数组的filter方法

var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
 var uniqArray9 = arr.filter(function(element, index,array) {
    return arr.lastIndexOf(element) === index;
    });
console.log(uniqArray9);
//[ 7, 1, "1", 5, 3, "3", "5" ]

方法九
思路:利用reduce方法

var arr = [1, 7, 7, 1, "1",3, 5, 3, "3", "5"];
   var uniqArray8 = function(a) {
       return a.reduce(function(p, c) {
           if (p.indexOf(c) < 0) p.push(c);
           return p;
       }, []);
    };
console.log(uniqArray8(arr));
//[ 1, 7, "1", 3, 5, "3", "5" ]

关于reduce方法的补充:
reduce()方法从数组的第一项开始,在每一项上调用函数,这个函数返回的任何值都会作为第一个参数自动传给下一项。

方法十
使用ES6的set方法。

Array.prototype.getUnique = function() {
    return [...new Set( [this] )];
};

方法十一
使用jQuery
实现:

//from:http://stackoverflow.com/questions/1960473/unique-values-in-an-array
(function($){
    var _old = $.unique;
    $.unique = function(arr){
        if (!!arr[0].nodeType){
            return _old.apply(this,arguments);
        } else {
            return $.grep(arr,function(v,k){
                return $.inArray(v,arr) === k;
            });
        }
    };
})(jQuery);

var arr = ["first",7,true,2,7,true,"last","last"];
$.unique(arr); 
// ["first", 7, true, 2, "last"]

var arr = [1,2,3,4,5,4,3,2,1];
$.unique(arr); 
// [1, 2, 3, 4, 5]
针对二维数组的去重方法

思路:通过isArray方法判断数组中是否还有数组,如果有数组,在该数组上再次遍历
实现:

//from: https://segmentfault.com/q/1010000000444289
var arr = [1,2,3,[1,1,2],[3,2],2];
var uniqArray11 = function(arr) {
    var result = arr.reduce(function(v, i) {
        //判断有没有二维数组
        if(Array.isArray(i)) {
            i.forEach(function(item) {
                if(v.indexOf(item) < 0) {
                    v.push(item);
                }
            });
        }else if(v.indexOf(i) < 0){
            v.push(i);
        }
        return v;
    }, []);
  return result;
};
console.log(uniqArray11(arr));
//[ 1, 2, 3 ]
针对对象的去重方法

实现:

//from:http://stackoverflow.com/questions/1960473/unique-values-in-an-array
Array.prototype.getUnique = function() {
        var hash = {}, result = [], key; 
        for ( var i = 0, l = this.length; i < l; ++i ) {
            key = JSON.stringify(this[i]);
            if ( !hash.hasOwnProperty(key) ) {
                hash[key] = true;
                result.push(this[i]);
            }
        }
        return result;
    };

var data = [
        {
            name: "aaa",
            value: 123
        },
        {
            name: "bbb",
            value: 234
        },
        {
            name: "aaa",
            value: 123
        },
        {
            name: "bbb",
            value: 789
        }
    ];
console.log(data.getUnique()); 
//[ { name: "aaa", value: 123 },
//  { name: "bbb", value: 234 },
//  { name: "bbb", value: 789 } ]
文章参考链接

下面是本文所述方法的来源链接:

http://www.cnblogs.com/wteam-xq/p/4732351.html

http://blog.jobbole.com/33099/

https://segmentfault.com/q/1010000000262609

https://segmentfault.com/q/1010000003864059

https://segmentfault.com/q/1010000000444289

http://stackoverflow.com/questions/1960473/unique-values-in-an-array

http://stackoverflow.com/questions/11246758/how-to-get-unique-values-in-an-array

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78891.html

相关文章

  • <javaScript> 数组去重的方法总结(2017年)

    摘要:现在要求去重下面这个数组测试重复重复方法一测试重复重复去重后测试重复是新加的集合集合中的值不会重复。欢迎大家一起讨论提出新的去重方法。有任何错误请在评论指出。 现在要求去重下面这个数组 [1, 2, 3, 3, 3, 0, 1, 2, 测试, 重复, 重复, NaN, NaN, false, false]; 方法一:ES6 Set() let arr = [1, 2, 3, 3, 3,...

    hightopo 评论0 收藏0
  • <javaScript> 数组去重的方法总结(2017年)

    摘要:现在要求去重下面这个数组测试重复重复方法一测试重复重复去重后测试重复是新加的集合集合中的值不会重复。欢迎大家一起讨论提出新的去重方法。有任何错误请在评论指出。 现在要求去重下面这个数组 [1, 2, 3, 3, 3, 0, 1, 2, 测试, 重复, 重复, NaN, NaN, false, false]; 方法一:ES6 Set() let arr = [1, 2, 3, 3, 3,...

    YanceyOfficial 评论0 收藏0
  • JavaScript数组去重总结

    摘要:数组去重方法的总结前言在中数组是比较常用的,本文中总结了下数组去重的几种常用方法,如有问题,请指正。 JavaScript数组去重方法的总结 前言 在JavaScript中数组是比较常用的,本文中总结了下数组去重的几种常用方法,如有问题,请指正。 简单粗暴的一种,ES6中set方法: var arr = [1,2,2,3,3,4,5,5]; console.log([...new Se...

    Tonny 评论0 收藏0
  • JS专题之数组去重

    摘要:将元素作为对象的键,默认键对应的值为如果对象中没有这个键,则将这个元素放入结果数组中去。 前言 数组去重在日常开发中的使用频率还是较高的,也是网上随便一抓一大把的话题,所以,我写这篇文章目的在于归纳和总结,既然很多人都在提的数组去重,自己到底了解多少呢。又或者是如果自己在开发中遇到了去重的需求,自己能想到更好的解决方案吗。 这次我们来理一理怎么做数组去重才能做得最合适,既要考虑兼容性,...

    only_do 评论0 收藏0
  • JavaScript系列--八种【数组去重】方法的总结

    摘要:缺点不兼容以下浏览器七高阶函数方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回,否则返回。方法六高阶函数优点高阶函数的高级用法。 一、前言 数组去重是一个老生常谈的问题,但是有时候会弹出点其他东西。 二、双重循环 这个方法是最常见的,最原始的方法。 // 方法一:双重循环 var array = [1,1,1,2,1,1,2] function unique(arr...

    Xufc 评论0 收藏0
  • JavaScript数组方法之数组去重方法

    摘要:工作过程中经常会用到数组去重,用到的时候往往一时想不到好方法,所以这里来总结一下去重方法。和方法分别为添加成员方法和得到键值方法。因此,利用方法也可以实现数组的去重。 工作过程中经常会用到数组去重,用到的时候往往一时想不到好方法,所以这里来总结一下去重方法。使用es6去重代码很简单,而且ES6已经相当普及了。所以先来介绍一下es6中的方法。 1.ES6中Map结构方法 function...

    CarlBenjamin 评论0 收藏0

发表评论

0条评论

shmily

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<