How to get unique values in an array

后端 未结 20 1924
情歌与酒
情歌与酒 2020-11-22 14:02

How can I get a list of unique values in an array? Do I always have to use a second array or is there something similar to java\'s hashmap in JavaScript?

I am going

相关标签:
20条回答
  • 2020-11-22 14:31

    Another thought of this question. Here is what I did to achieve this with fewer code.

    var distinctMap = {};
    var testArray = ['John', 'John', 'Jason', 'Jason'];
    for (var i = 0; i < testArray.length; i++) {
      var value = testArray[i];
      distinctMap[value] = '';
    };
    var unique_values = Object.keys(distinctMap);
    
    console.log(unique_values);

    0 讨论(0)
  • 2020-11-22 14:32

    Using jQuery, here's an Array unique function I made:

    Array.prototype.unique = function () {
        var arr = this;
        return $.grep(arr, function (v, i) {
            return $.inArray(v, arr) === i;
        });
    }
    
    console.log([1,2,3,1,2,3].unique()); // [1,2,3]
    
    0 讨论(0)
  • 2020-11-22 14:34

    Since I went on about it in the comments for @Rocket's answer, I may as well provide an example that uses no libraries. This requires two new prototype functions, contains and unique

    Array.prototype.contains = function(v) {
      for (var i = 0; i < this.length; i++) {
        if (this[i] === v) return true;
      }
      return false;
    };
    
    Array.prototype.unique = function() {
      var arr = [];
      for (var i = 0; i < this.length; i++) {
        if (!arr.contains(this[i])) {
          arr.push(this[i]);
        }
      }
      return arr;
    }
    
    var duplicates = [1, 3, 4, 2, 1, 2, 3, 8];
    var uniques = duplicates.unique(); // result = [1,3,4,2,8]
    
    console.log(uniques);

    For more reliability, you can replace contains with MDN's indexOf shim and check if each element's indexOf is equal to -1: documentation

    0 讨论(0)
  • 2020-11-22 14:34

    If you want to leave the original array intact,

    you need a second array to contain the uniqe elements of the first-

    Most browsers have Array.prototype.filter:

    var unique= array1.filter(function(itm, i){
        return array1.indexOf(itm)== i; 
        // returns true for only the first instance of itm
    });
    
    
    //if you need a 'shim':
    Array.prototype.filter= Array.prototype.filter || function(fun, scope){
        var T= this, A= [], i= 0, itm, L= T.length;
        if(typeof fun== 'function'){
            while(i<L){
                if(i in T){
                    itm= T[i];
                    if(fun.call(scope, itm, i, T)) A[A.length]= itm;
                }
                ++i;
            }
        }
        return A;
    }
     Array.prototype.indexOf= Array.prototype.indexOf || function(what, i){
            if(!i || typeof i!= 'number') i= 0;
            var L= this.length;
            while(i<L){
                if(this[i]=== what) return i;
                ++i;
            }
            return -1;
        }
    
    0 讨论(0)
  • 2020-11-22 14:35

    Or for those looking for a one-liner (simple and functional), compatible with current browsers:

    let a = ["1", "1", "2", "3", "3", "1"];
    let unique = a.filter((item, i, ar) => ar.indexOf(item) === i);
    console.log(unique);

    Update 18-04-2017

    It appears as though 'Array.prototype.includes' now has widespread support in the latest versions of the mainline browsers (compatibility)

    Update 29-07-2015:

    There are plans in the works for browsers to support a standardized 'Array.prototype.includes' method, which although does not directly answer this question; is often related.

    Usage:

    ["1", "1", "2", "3", "3", "1"].includes("2");     // true
    

    Pollyfill (browser support, source from mozilla):

    // https://tc39.github.io/ecma262/#sec-array.prototype.includes
    if (!Array.prototype.includes) {
      Object.defineProperty(Array.prototype, 'includes', {
        value: function(searchElement, fromIndex) {
    
          // 1. Let O be ? ToObject(this value).
          if (this == null) {
            throw new TypeError('"this" is null or not defined');
          }
    
          var o = Object(this);
    
          // 2. Let len be ? ToLength(? Get(O, "length")).
          var len = o.length >>> 0;
    
          // 3. If len is 0, return false.
          if (len === 0) {
            return false;
          }
    
          // 4. Let n be ? ToInteger(fromIndex).
          //    (If fromIndex is undefined, this step produces the value 0.)
          var n = fromIndex | 0;
    
          // 5. If n ≥ 0, then
          //  a. Let k be n.
          // 6. Else n < 0,
          //  a. Let k be len + n.
          //  b. If k < 0, let k be 0.
          var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
    
          // 7. Repeat, while k < len
          while (k < len) {
            // a. Let elementK be the result of ? Get(O, ! ToString(k)).
            // b. If SameValueZero(searchElement, elementK) is true, return true.
            // c. Increase k by 1.
            // NOTE: === provides the correct "SameValueZero" comparison needed here.
            if (o[k] === searchElement) {
              return true;
            }
            k++;
          }
    
          // 8. Return false
          return false;
        }
      });
    }
    
    0 讨论(0)
  • 2020-11-22 14:37

    One Liner, Pure JavaScript

    With ES6 syntax

    list = list.filter((x, i, a) => a.indexOf(x) === i)

    x --> item in array
    i --> index of item
    a --> array reference, (in this case "list")
    

    With ES5 syntax

    list = list.filter(function (x, i, a) { 
        return a.indexOf(x) === i; 
    });
    

    Browser Compatibility: IE9+

    0 讨论(0)
提交回复
热议问题