jQuery function to get all unique elements from an array?

JavascriptJqueryJquery Selectors

Javascript Problem Overview


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.)

Javascript Solutions


Solution 1 - Javascript

You can use array.filter to return the first item of each distinct value-

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

var unique = a.filter(function(itm, i, a) {
    return i == a.indexOf(itm);
});

console.log(unique);

If supporting IE8 and below is primary, don't use the unsupported filter method.

Otherwise,

if (!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;
	}
}

Solution 2 - Javascript

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]);

Solution 3 - Javascript

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]

Solution 4 - Javascript

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

Solution 5 - Javascript

    // 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/

Solution 6 - Javascript

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;
};

Solution 7 - Javascript

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);

Solution 8 - Javascript

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"] 

Solution 9 - Javascript

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;
}

Solution 10 - Javascript

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.

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

console.log(uniqueArr);

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.

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

console.log(uniqueArr);

Solution 11 - Javascript

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]

Solution 12 - Javascript

If anyone is using knockoutjs try:

ko.utils.arrayGetDistinctValues()

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

Solution 13 - Javascript

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

Example

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

Solution 14 - Javascript

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);
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCrashalotView Question on Stackoverflow
Solution 1 - JavascriptkennebecView Answer on Stackoverflow
Solution 2 - Javascriptjs1568View Answer on Stackoverflow
Solution 3 - JavascriptDennisView Answer on Stackoverflow
Solution 4 - JavascriptlawnseaView Answer on Stackoverflow
Solution 5 - JavascriptRubyriderView Answer on Stackoverflow
Solution 6 - JavascriptNoneView Answer on Stackoverflow
Solution 7 - JavascriptMottieView Answer on Stackoverflow
Solution 8 - JavascriptDariozzoView Answer on Stackoverflow
Solution 9 - JavascriptjaggedsoftView Answer on Stackoverflow
Solution 10 - JavascriptVadim OvchinnikovView Answer on Stackoverflow
Solution 11 - JavascriptKristian AbrahamsenView Answer on Stackoverflow
Solution 12 - JavascriptTorbjörn NomellView Answer on Stackoverflow
Solution 13 - JavascriptJoseph N.View Answer on Stackoverflow
Solution 14 - JavascriptBoricView Answer on Stackoverflow