[javascript] jQuery function to get all unique elements from an array?

jQuery.unique lets you get unique elements of an array, but the docs say the function is mostly for internal use and only operates on DOM elements. Another SO response said the unique() function worked on numbers, but that this use case is not necessarily future proof because it's not explicitly stated in the docs.

Given this, is there a "standard" jQuery function for accessing only the unique values — specifically, primitives like integers — in an array? (Obviously, we can construct a loop with the each() function, but we are new to jQuery and would like to know if there is a dedicated jQuery function for this.)

This question is related to javascript jquery jquery-selectors

The answer is


If you need to support IE 8 or earlier, you can use jQuery to accomplish this.

var a = [1,2,2,3,4,3,5];
var unique = $.grep(a, function (item, index) {
   return index === $.inArray(item, a);
});

Just use this code as the basis of a simple JQuery plugin.

$.extend({
    distinct : function(anArray) {
       var result = [];
       $.each(anArray, function(i,v){
           if ($.inArray(v, result) == -1) result.push(v);
       });
       return result;
    }
});

Use as so:

$.distinct([0,1,2,2,3]);

Paul Irish has a "Duck Punching" method (see example 2) that modifies jQuery's $.unique() method to return unique elements of any type:

(function($){
    var _old = $.unique;
    $.unique = function(arr){
        // do the default behavior only if we got an array of elements
        if (!!arr[0].nodeType){
            return _old.apply(this,arguments);
        } else {
            // reduce the array to contain no dupes via grep/inArray
            return $.grep(arr,function(v,k){
                return $.inArray(v,arr) === k;
            });
        }
    };
})(jQuery);

You can use a jQuery plugin called Array Utilities to get an array of unique items. It can be done like this:

var distinctArray = $.distinct([1, 2, 2, 3])

distinctArray = [1,2,3]


function array_unique(array) {
    var unique = [];
    for ( var i = 0 ; i < array.length ; ++i ) {
        if ( unique.indexOf(array[i]) == -1 )
            unique.push(array[i]);
    }
    return unique;
}

If anyone is using knockoutjs try:

ko.utils.arrayGetDistinctValues()

BTW have look at all ko.utils.array* utilities.


Based on @kennebec's answer, but fixed for IE8 and below by using jQuery wrappers around the array to provide missing Array functions filter and indexOf:

$.makeArray() wrapper might not be absolutely needed, but you'll get odd results if you omit this wrapper and JSON.stringify the result otherwise.

var a = [1,5,1,6,4,5,2,5,4,3,1,2,6,6,3,3,2,4];

// note: jQuery's filter params are opposite of javascript's native implementation :(
var unique = $.makeArray($(a).filter(function(i,itm){ 
    // note: 'index', not 'indexOf'
    return i == $(a).index(itm);
}));

// unique: [1, 5, 6, 4, 2, 3]

this is js1568's solution, modified to work on a generic array of objects, like:

 var genericObject=[
        {genProp:'this is a string',randomInt:10,isBoolean:false},
        {genProp:'this is another string',randomInt:20,isBoolean:false},
        {genProp:'this is a string',randomInt:10,isBoolean:true},
        {genProp:'this is another string',randomInt:30,isBoolean:false},
        {genProp:'this is a string',randomInt:40,isBoolean:true},
        {genProp:'i like strings',randomInt:60,isBoolean:true},
        {genProp:'this is a string',randomInt:70,isBoolean:true},
        {genProp:'this string is unique',randomInt:50,isBoolean:true},
        {genProp:'this is a string',randomInt:50,isBoolean:false},
        {genProp:'i like strings',randomInt:70,isBoolean:false}
    ]

It accepts one more parameter called propertyName, guess! :)

  $.extend({
        distinctObj:function(obj,propertyName) {
            var result = [];
            $.each(obj,function(i,v){
                var prop=eval("v."+propertyName);
                if ($.inArray(prop, result) == -1) result.push(prop);
            });
            return result;
        }
    });

so, if you need to extract a list of unique values for a given property, for example the values used for randomInt property, use this:

$.distinctObj(genericObject,'genProp');

it returns an array like this:

["this is a string", "this is another string", "i like strings", "this string is unique"] 

Plain JavaScript modern solution if you don't need IE support (Array.from is not supported in IE).

You can use combination of Set and Array.from.

_x000D_
_x000D_
const arr = [1, 1, 11, 2, 4, 2, 5, 3, 1];_x000D_
const set = new Set(arr);_x000D_
const uniqueArr = Array.from(set);_x000D_
_x000D_
console.log(uniqueArr);
_x000D_
_x000D_
_x000D_

The Set object lets you store unique values of any type, whether primitive values or object references.

The Array.from() method creates a new Array instance from an array-like or iterable object.

Also Array.from() can be replaced with spread operator.

_x000D_
_x000D_
const arr = [1, 1, 11, 2, 4, 2, 5, 3, 1];_x000D_
const set = new Set(arr);_x000D_
const uniqueArr = [...set];_x000D_
_x000D_
console.log(uniqueArr);
_x000D_
_x000D_
_x000D_


As of jquery 3.0 you can use $.uniqueSort(ARRAY)

Example

array = ["1","2","1","2"]
$.uniqueSort(array)
=> ["1", "2"]

I would use underscore.js, which provides a uniq method that does what you want.


Walk the array and push items into a hash as you come across them. Cross-reference the hash for each new element.

Note that this will ONLY work properly for primitives (strings, numbers, null, undefined, NaN) and a few objects that serialize to the same thing (functions, strings, dates, possibly arrays depending on content). Hashes in this will collide as they all serialize to the same thing, e.g. "[object Object]"

Array.prototype.distinct = function(){
   var map = {}, out = [];

   for(var i=0, l=this.length; i<l; i++){
      if(map[this[i]]){ continue; }

      out.push(this[i]);
      map[this[i]] = 1;
   }

   return out;
}

There's also no reason you can't use jQuery.unique. The only thing I don't like about it is that it destroys the ordering of your array. Here's the exact code for it if you're interested:

Sizzle.uniqueSort = function(results){
    if ( sortOrder ) {
        hasDuplicate = baseHasDuplicate;
        results.sort(sortOrder);

        if ( hasDuplicate ) {
            for ( var i = 1; i < results.length; i++ ) {
                if ( results[i] === results[i-1] ) {
                    results.splice(i--, 1);
                }
            }
        }
    }

    return results;
};

    // for numbers
    a = [1,3,2,4,5,6,7,8, 1,1,4,5,6]
    $.unique(a)
    [7, 6, 1, 8, 3, 2, 5, 4]

    // for string
    a = ["a", "a", "b"]
    $.unique(a)
    ["b", "a"]

And for dom elements there is no example is needed here I guess because you already know that!

Here is the jsfiddle link of live example: http://jsfiddle.net/3BtMc/4/


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to jquery-selectors

Why is my JQuery selector returning a n.fn.init[0], and what is it? How to use placeholder as default value in select2 framework Access the css ":after" selector with jQuery jQuery: using a variable as a selector Check if any ancestor has a class using jQuery jQuery selector first td of each row Select element by exact match of its content jQuery selector to get form by name jQuery : select all element with custom attribute Set select option 'selected', by value