Last Updated: September 09, 2019
·
107.1K
· Tamer Shlash

Simple & Pure JavaScript Array.unique method with 5 lines of code

It's often to have an array that contains duplicate values and you want to make them unique. For example, you might have ["a", 1, "a", 2, "1", 1] and want to get ["a", 1, 2, "1"].

Utilizing many features in JavaScript like prototypes and anonymous functions, you can get that result with 5 lines of code:

Array.prototype.unique = function() {
  return this.filter(function (value, index, self) { 
    return self.indexOf(value) === index;
  });
}

Usage:

var arr = ['a', 1, 'a', 2, '1']
arr.unique(); // => ['a', 1, 2, '1']

This solution does NOT require any dependencies like jQuery or prototype.js, and it works for arrays with mixed types!

How does it work?

  • The native method filter will loop through the array and leave only those entries that pass (i.e get true return value) the given callback anonymous function.

  • The callback anonymous function returns true if the entry is the first occurrence, and false elsewhere. It uses the native indexOf method which finds the index of the first occurrence of an entry in an array.

Talking about filter and indexOf native methods, they were introduced in ECMA-262 standard 5th edition, which means they are not supported in old browsers (<IE9). There are workarounds for filter and indexOf to get the same method to work, but it will no longer be a 5-lines code.

Reference: This protip is based on this answer.

3 Responses
Add your response

This is very nice, just a footnote, this only works with flat arrays, for example calling .uniq on arr = [[1], [1], [1]] does not work. This will require a more sophisticated solution based on item type.

over 1 year ago ·

But keep in mind this is a O(n^2) solution.

over 1 year ago ·

This is a really nice and compact solution, however I found it didn't work with objects. I have a version that does take into account objects and mixed value arrays:

var j = {};

this.forEach(function (v) {
  var typ = (typeof v === 'object') ? 'object' : typeof v;
  var v = (typ === 'object') ? JSON.stringify(v) : v;

  j[v + '::' + typ] = v;
});

return Object.keys(j).map(function (v) {
  if (v.indexOf('::object') > -1) {
    return JSON.parse(j[v]);
  }

  return j[v];
});
over 1 year ago ·