[javascript] Get all unique values in a JavaScript array (remove duplicates)

I have an array of numbers that I need to make sure are unique. I found the code snippet below on the internet and it works great until the array has a zero in it. I found this other script here on Stack Overflow that looks almost exactly like it, but it doesn't fail.

So for the sake of helping me learn, can someone help me determine where the prototype script is going wrong?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.push (e)};
 return a;
}

More answers from duplicate question:

Similar question:

This question is related to javascript arrays duplicates set unique

The answer is


Multiple way to remove duplicate elements from an Array using

  • set
  • filter
  • forEach
  • lodash(third party library)
  • for loop

_x000D_
_x000D_
const names = ['XYZ', 'ABC', '123', 'ABC', 'ACE', 'ABC', '123'];_x000D_
_x000D_
// set_x000D_
let unique = [...new Set(names)];_x000D_
console.log(unique);_x000D_
_x000D_
// filter_x000D_
let x = (names) => names.filter((val,i) => names.indexOf(val) === i)_x000D_
console.log(x(names));_x000D_
_x000D_
_x000D_
// forEach_x000D_
function removeDuplicates(names) {_x000D_
  let unique = {};_x000D_
  names.forEach(function(i) {_x000D_
    if(!unique[i]) {_x000D_
      unique[i] = true;_x000D_
    }_x000D_
  });_x000D_
  return Object.keys(unique);_x000D_
}_x000D_
_x000D_
console.log(removeDuplicates(names));
_x000D_
_x000D_
_x000D_

Using lodash

npm i lodash

code

import _ from 'lodash';

let uniqueVal = _.uniq (names);
console.dir(uniqueVal);

Using simple for loop

_x000D_
_x000D_
const names = ['XYZ', 'ABC', '123', 'ABC', 'ACE', 'ABC', '123'];_x000D_
let unique=[];_x000D_
names.sort();_x000D_
let len = names.length;_x000D_
for(let i=0;i<len;i++){_x000D_
    if(names[i]!==names[i+1])_x000D_
    unique.push(names[i])_x000D_
}_x000D_
console.log(unique)
_x000D_
_x000D_
_x000D_


Use this without using any function and time complexity of O(n)

function uni(arr){
   var i = 0,uk = 0;
    for (j = 1; j < arr.length; j++){
        if(arr[i] != arr[j]){
            uk++;
            i = j;
        }

    }
    return uk + 1;
}

This has been answered a lot, but it didn't address my particular need.

Many answers are like this:

a.filter((item, pos, self) => self.indexOf(item) === pos);

But this doesn't work for arrays of complex objects.

Say we have an array like this:

const a = [
 { age: 4, name: 'fluffy' },
 { age: 5, name: 'spot' },
 { age: 2, name: 'fluffy' },
 { age: 3, name: 'toby' },
];

If we want the objects with unique names, we should use array.prototype.findIndex instead of array.prototype.indexOf:

a.filter((item, pos, self) => self.findIndex(v => v.name === item.name) === pos);

If you have the mighty reduce method available (≥ 5.1), you can try something like this:

Array.prototype.uniq = function() {
  return this.reduce(function(sofar, cur) {
    return sofar.indexOf(cur) < 0 ? sofar.concat([cur]) : sofar;
  }, []);
};

It's not the most efficient implementation (because of the indexOf check, which may in the worst case go through the entire list). If efficiency matters, you can keep the "history" of occurrences in some random-access structure (say, {}) and key those instead. That's basically what the most voted answer does, so check that out for an example.


If order is not important then we can make an hash and get the keys to make unique array.

var ar = [1,3,4,5,5,6,5,6,2,1];
var uarEle = {};
links.forEach(function(a){ uarEle[a] = 1; });
var uar = keys(uarEle)

uar will be having the unique array elements.


Without extending Array.prototype (it is said to be a bad practice) or using jquery/underscore, you can simply filter the array.

By keeping last occurrence:

    function arrayLastUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps last occurrence
            return c.indexOf(a, b + 1) < 0;
        });
    },

or first occurrence:

    function arrayFirstUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps first occurrence
            return c.indexOf(a) === b;
        });
    },

Well, it's only javascript ECMAScript 5+, which means only IE9+, but it's nice for a development in native HTML/JS (Windows Store App, Firefox OS, Sencha, Phonegap, Titanium, ...).


This should have better performance than the variant with list.indexOf

function uniq(list) { return [...new Set(list)] }

You can also use sugar.js:

[1,2,2,3,1].unique() // => [1,2,3]

[{id:5, name:"Jay"}, {id:6, name:"Jay"}, {id: 5, name:"Jay"}].unique('id') 
  // => [{id:5, name:"Jay"}, {id:6, name:"Jay"}]

To filter-out undefined and null values because most of the time you do not need them.

const uniques = myArray.filter(e => e).filter((e, i, a) => a.indexOf(e) === i);

or

const uniques = [...new Set(myArray.filter(e => e))];

I have a solution that uses es6 reduce and find array helper methods to remove duplicates.

_x000D_
_x000D_
let numbers = [2, 2, 3, 3, 5, 6, 6];_x000D_
_x000D_
const removeDups = array => {_x000D_
  return array.reduce((acc, inc) => {_x000D_
    if (!acc.find(i => i === inc)) {_x000D_
      acc.push(inc);_x000D_
    }_x000D_
    return acc;_x000D_
  }, []);_x000D_
}_x000D_
_x000D_
console.log(removeDups(numbers)); /// [2,3,5,6]
_x000D_
_x000D_
_x000D_


That's because 0 is a falsy value in JavaScript.

this[i] will be falsy if the value of the array is 0 or any other falsy value.


If you have an array of objects, and you want a uniqueBy function, say, by an id field:

function uniqueBy(field, arr) {
   return arr.reduce((acc, curr) => {
     const exists = acc.find(v => v[field] === curr[field]);
     return exists ? acc : acc.concat(curr);
   }, [])
}

   var elems = ['f', 'a','b','f', 'c','d','e','f','c', 'n', 'n'];

    elems.sort();

    elems.forEach(function (value, index, arr){

        let first_index = arr.indexOf(value);
        let last_index = arr.lastIndexOf(value);

         if(first_index === last_index){

         console.log('unique items in array ' + value);

         }else{

         console.log('Duplicate item in array ' + value);             

         }

    });

I use this extrem simple one and I am pretty sure it is compatible to every browser but it is obsolete in modern browsers:

_x000D_
_x000D_
var keys = [1,3,3,3,3,2,2,1,4,4,'aha','aha'];
for (var uniqueIdx = 0; uniqueIdx < keys.length; uniqueIdx++) {
  for (var duplicateCandidateIdx=0; duplicateCandidateIdx < keys.length; duplicateCandidateIdx++) {
    if(uniqueIdx != duplicateCandidateIdx) {
      var candidateIsFullDuplicate = keys[uniqueIdx] == keys[duplicateCandidateIdx];
      if (candidateIsFullDuplicate){
        keys.splice(duplicateCandidateIdx, 1);
      }
    }
  }
}
document.write(keys); // gives: 1,3,2,4,aha
_x000D_
_x000D_
_x000D_


Array.prototype.unique = function() {
    var a = [],k = 0,e;
    for(k=0;e=this[k];k++)
      if(a.indexOf(e)==-1)
           a.push(e);
    return a;
}
[1,2,3,4,33,23,2,3,22,1].unique(); // return [1,2,3,4,33,23,22]

We can do this using ES6 sets:

_x000D_
_x000D_
var duplicatedArray = [1, 2, 3, 4, 5, 1, 1, 1, 2, 3, 4];_x000D_
var uniqueArray = Array.from(new Set(duplicatedArray));_x000D_
_x000D_
console.log(uniqueArray);
_x000D_
_x000D_
_x000D_

//The output will be

uniqueArray = [1,2,3,4,5];

I looked at Joeytje50's code on jsperf who has compared a number of alternatives. His code had many minor typos, which made a difference in the performance and the correctness.

More importantly, he is testing on a very small array. I made an array with 1000 integers. Each integer was 100 times a random integer between 0 and 1000. This makes for about 1000/e = 368 duplicates on the average. The results are at jsperf.

This is a much more realistic scenario of where efficiency might be needed. These changes make dramatic changes in the claims (specifically the code touted as fastest is nowhere near fast). The obvious winners are where hashing techniques are used, with the best one being

Array.prototype.getUnique3 = function(){
   var u = Object.create(null), a = [];
   for(var i = 0, l = this.length; i < l; ++i){
      if(this[i] in u) continue;
      a.push(this[i]);
      u[this[i]] = 1;
   }
   return a.length;
}

Making an array of unique arrays, using field[2] as an Id:

_x000D_
_x000D_
const arr = [_x000D_
  ['497', 'Q0', 'WTX091-B06-138', '0', '1.000000000', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B09-92', '1', '0.866899288', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B09-92', '2', '0.846036819', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B09-57', '3', '0.835025326', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B43-79', '4', '0.765068215', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B43-56', '5', '0.764211464', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B44-448', '6', '0.761701704', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B44-12', '7', '0.761701704', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B49-128', '8', '0.747434800', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B18-17', '9', '0.746724770', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B19-374', '10', '0.733379549', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B19-344', '11', '0.731421782', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B09-92', '12', '0.726450470', 'GROUP001'],_x000D_
  ['497', 'Q0', 'WTX091-B19-174', '13', '0.712757036', 'GROUP001']_x000D_
];_x000D_
_x000D_
_x000D_
arr.filter((val1, idx1, arr) => !!~val1.indexOf(val1[2]) &&_x000D_
  !(arr.filter((val2, idx2) => !!~val2.indexOf(val1[2]) &&_x000D_
    idx2 < idx1).length));_x000D_
_x000D_
console.log(arr);
_x000D_
_x000D_
_x000D_


array.forEach for traversing each element through the array and the if condition checking if the new array contains the element already. Hope this helps!!

    var arr = [1, 2, 2, 3, 4, 5, 6, 7, 7, 7, 7, 8, 9, 4, 3, 3, 5];
    let arr1 = [];
    arr.forEach(elem => {
        if (!arr1.includes(elem)) {
            arr1.push(elem);
        }
    });
    console.log(arr1);

Do it with lodash and identity lambda function, just define it before use your object

const _ = require('lodash');
...    
_.uniqBy([{a:1,b:2},{a:1,b:2},{a:1,b:3}], v=>v.a.toString()+v.b.toString())
_.uniq([1,2,3,3,'a','a','x'])

and will have:

[{a:1,b:2},{a:1,b:3}]
[1,2,3,'a','x']

(this is the simplest way )


Array.prototype.getUnique = function() {
    var o = {}, a = []
    for (var i = 0; i < this.length; i++) o[this[i]] = 1
    for (var e in o) a.push(e)
    return a
}

I have a simple example where we can remove objects from array having repeated id in objects,

  let data = new Array({id: 1},{id: 2},{id: 3},{id: 1},{id: 3});
  let unique = [];
  let tempArr = [];
  console.log('before', data);
  data.forEach((value, index) => {
    if (unique.indexOf(value.id) === -1) {
      unique.push(value.id);
    } else {
      tempArr.push(index);    
    }
  });
  tempArr.reverse();
  tempArr.forEach(ele => {
    data.splice(ele, 1);
  });
  console.log(data);

Using object keys to make unique array, I have tried following

function uniqueArray( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });


  return Object.keys(j).map(function(v){
    return j[v];
  });
}   

uniqueArray(["1",1,2,3,4,1,"foo", false, false, null,1]);

Which returns ["1", 1, 2, 3, 4, "foo", false, null]


You can also use underscore.js.

_x000D_
_x000D_
console.log(_.uniq([1, 2, 1, 3, 1, 4]));
_x000D_
<script src="http://underscorejs.org/underscore-min.js"></script>
_x000D_
_x000D_
_x000D_

which will return:

[1, 2, 3, 4]

Yet another solution for the pile.

I recently needed to make a sorted list unique and I did it using filter that keeps track of the previous item in an object like this:

uniqueArray = sortedArray.filter(function(e) { 
    if(e==this.last) 
      return false; 
    this.last=e; return true;  
  },{last:null});

Using Array.prototype.includes() method to remove duplicates:

(function() {
    const array = [1, 1, 2, 2, 3, 5, 5, 2];
    let uniqueValues = [];
    array.map(num => {
        if (Number.isInteger(num) && !uniqueValues.includes(num)) {
            uniqueValues.push(num)
        }
    });
    console.log(uniqueValues)
}());

It appears we have lost Rafael's answer, which stood as the accepted answer for a few years. This was (at least in 2017) the best-performing solution if you don't have a mixed-type array:

Array.prototype.getUnique = function(){
    var u = {}, a = [];
    for (var i = 0, l = this.length; i < l; ++i) {
        if (u.hasOwnProperty(this[i])) {
            continue;
        }
        a.push(this[i]);
        u[this[i]] = 1;
    }
return a;
}

If you do have a mixed-type array, you can serialize the hash key:

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

Updated answer for ES6/ES2015: Using the Set and the spread operator (thanks le-m), the single line solution is:

let uniqueItems = [...new Set(items)]

Which returns

[4, 5, 6, 3, 2, 23, 1]

For an object-based array with some unique id's, I have a simple solution through which you can sort in linear complexity

function getUniqueArr(arr){
    const mapObj = {};
    arr.forEach(a => { 
       mapObj[a.id] = a
    })
    return Object.values(mapObj);
}

You can also use jQuery

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]

Originally answered at: jQuery function to get all unique elements from an array?


This prototype getUnique is not totally correct, because if i have a Array like: ["1",1,2,3,4,1,"foo"] it will return ["1","2","3","4"] and "1" is string and 1 is a integer; they are different.

Here is a correct solution:

Array.prototype.unique = function(a){
    return function(){ return this.filter(a) }
}(function(a,b,c){ return c.indexOf(a,b+1) < 0 });

using:

var foo;
foo = ["1",1,2,3,4,1,"foo"];
foo.unique();

The above will produce ["1",2,3,4,1,"foo"].


I think this this is most easiest way to get unique item from array.

var arr = [1,2,4,1,4];
arr = Array.from(new Set(arr))
console.log(arr)

I used Array#reduce as way to create Array#unique

_x000D_
_x000D_
Array.prototype.unique = function() {_x000D_
  var object = this.reduce(function(h, v) {_x000D_
    h[v] = true;_x000D_
    return h;_x000D_
  }, {});_x000D_
  return Object.keys(object);_x000D_
}_x000D_
_x000D_
console.log(["a", "b", "c", "b", "c", "a", "b"].unique()); // => ["a", "b", "c"]
_x000D_
_x000D_
_x000D_


The simplest method to find unique element using filter method:

_x000D_
_x000D_
var A1 = [2, 2, 4, 5, 5, 6, 8, 8, 9];

var uniqueA1 = A1.filter(function(element) {
  return A1.indexOf(element) == A1.lastIndexOf(element);
});

console.log(uniqueA1); // Output: [4,6,9]
_x000D_
_x000D_
_x000D_

Here the logic is that the first and the last occurrence of an element are the same then this element occurs only once, so the array elements which pass the callback condition are included in the new array and displayed.


If you want to change it in place (not creating a new array) you can just:

var
  uniq = function uniq(array) {
    var
      len = array.length;

    while (len--) {
      if (array.indexOf(array[len]) !== len) {
        array.splice(len, 1);
      }
    }

    return array;
  },

  myArray = [1, 2, 2, 4, 2];

console.log(uniq(myArray));
// [1, 2, 4];

in my solution, I sort data before filtering :

const uniqSortedArray = dataArray.sort().filter((v, idx, t) => idx==0 || v != t[idx-1]); 

_x000D_
_x000D_
var numbers = [1, 1, 2, 3, 4, 4];_x000D_
_x000D_
function unique(dupArray) {_x000D_
  return dupArray.reduce(function(previous, num) {_x000D_
_x000D_
    if (previous.find(function(item) {_x000D_
        return item == num;_x000D_
      })) {_x000D_
      return previous;_x000D_
    } else {_x000D_
      previous.push(num);_x000D_
      return previous;_x000D_
    }_x000D_
  }, [])_x000D_
}_x000D_
_x000D_
var check = unique(numbers);_x000D_
console.log(check);
_x000D_
_x000D_
_x000D_


Similar to @sergeyz solution, but more compact by using more shorthand formats such as arrow functions and array.includes. Warning: JSlint will complain due to the use of the logical or and comma. (still perfectly valid javascript though)

my_array.reduce((a,k)=>(a.includes(k)||a.push(k),a),[])

Use .toString() for strings.

var givenvalues = [1,2,3,3,4,5,6];
var values = [];
for(var i=0; i<givenvalues.length; i++)
{
    if(values.indexOf(givenvalues[i]) == -1)
    {
        values[values.length] = givenvalues[i];
    }
}

I have since found a nice method that uses jQuery

arr = $.grep(arr, function(v, k){
    return $.inArray(v ,arr) === k;
});

Note: This code was pulled from Paul Irish's duck punching post - I forgot to give credit :P


 Array.prototype.unique=function(){ 

   var cr=[];

  this.forEach(function(entry) {
   if(cr.indexOf(entry)<0){
     cr.push(entry);
   }else{
    var index = cr.indexOf(entry);
    if (index > -1) {
     cr.splice(index, 1);
      }
   } 

 });

 return cr;
}

You can use Ramda.js, a functional javascript library to do this:

_x000D_
_x000D_
var unique = R.uniq([1, 2, 1, 3, 1, 4])_x000D_
console.log(unique)
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
_x000D_
_x000D_
_x000D_


PERFORMANCE ONLY! this code is probably 10X faster than all the codes in here *works on all browsers and also has the lowest memory impact.... and more

if you don't need to reuse the old array;btw do the necessary other operations before you convert it to unique here is probably the fastest way to do this, also very short.

var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];

then you can try this

_x000D_
_x000D_
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1];_x000D_
_x000D_
function toUnique(a, b, c) { //array,placeholder,placeholder_x000D_
  b = a.length;_x000D_
  while (c = --b)_x000D_
    while (c--) a[b] !== a[c] || a.splice(c, 1);_x000D_
  return a // not needed ;)_x000D_
}_x000D_
console.log(toUnique(array));_x000D_
//[3, 4, 5, 6, 7, 8, 9, 0, 2, 1]
_x000D_
_x000D_
_x000D_

I came up with this function reading this article...

http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/

I don't like the for loop. it has to many parameters.i like the while-- loop. while is the fastest loop in all browsers except the one we all like so much... chrome.

anyway i wrote the first function that uses while.And yep it's a little faster than the function found in the article.but not enough.unique2()

next step use modern js.Object.keys i replaced the other for loop with js1.7's Object.keys... a little faster and shorter (in chrome 2x faster) ;). Not enough!.unique3().

at this point i was thinking about what i really need in MY unique function. i don't need the old array, i want a fast function. so i used 2 while loops + splice.unique4()

Useless to say that i was impressed.

chrome: the usual 150,000 operations per second jumped to 1,800,000 operations per second.

ie: 80,000 op/s vs 3,500,000 op/s

ios: 18,000 op/s vs 170,000 op/s

safari: 80,000 op/s vs 6,000,000 op/s

Proof http://jsperf.com/wgu or better use console.time... microtime... whatever

unique5() is just to show you what happens if you want to keep the old array.

Don't use Array.prototype if yu don't know what your doing. i just did alot of copy and past. Use Object.defineProperty(Array.prototype,...,writable:false,enumerable:false}) if you want to create a native prototype.example: https://stackoverflow.com/a/20463021/2450730

Demo http://jsfiddle.net/46S7g/

NOTE: your old array is destroyed/becomestheunique after this operation.

if you can't read the code above ask, read a javascript book or here are some explainations about shorter code. https://stackoverflow.com/a/21353032/2450730

some are using indexOf ... don't ... http://jsperf.com/dgfgghfghfghghgfhgfhfghfhgfh

for empty arrays

!array.length||toUnique(array); 

You don't need .indexOf() at all; you can do this O(n):

function SelectDistinct(array) {
    const seenIt = new Set();

    return array.filter(function (val) {
        if (seenIt.has(val)) { 
            return false;
        }

        seenIt.add(val);

        return true;
    });
}

var hasDuplicates = [1,2,3,4,5,5,6,7,7];
console.log(SelectDistinct(hasDuplicates)) //[1,2,3,4,5,6,7]

If you don't want to use .filter():

function SelectDistinct(array) {
    const seenIt = new Set();
    const distinct = [];

    for (let i = 0; i < array.length; i++) {
        const value = array[i];

        if (!seenIt.has(value)) {
            seenIt.add(value);
            distinct.push(value);
        }
    }
    
    return distinct; 
    /* you could also drop the 'distinct' array and return 'Array.from(seenIt)', which converts the set object to an array */
}

If you're using Prototype framework there is no need to do 'for' loops, you can use http://www.prototypejs.org/api/array/uniq like this:

var a = Array.uniq();  

Which will produce a duplicate array with no duplicates. I came across your question searching a method to count distinct array records so after

uniq()

I used

size()

and there was my simple result. p.s. Sorry if i misstyped something

edit: if you want to escape undefined records you may want to add

compact()

before, like this:

var a = Array.compact().uniq();  

Shortest solution with ES6: [...new Set( [1, 1, 2] )];

Or if you want to modify the Array prototype (like in the original question):

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

EcmaScript 6 is only partially implemented in modern browsers at the moment (Aug. 2015), but Babel has become very popular for transpiling ES6 (and even ES7) back to ES5. That way you can write ES6 code today!

If you're wondering what the ... means, it's called the spread operator. From MDN: «The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected». Because a Set is an iterable (and can only have unique values), the spread operator will expand the Set to fill the array.

Resources for learning ES6:


The easiest way is to transform values into strings to filter also nested objects values.

const uniq = (arg = []) => {
  const stringifyedArg = arg.map(value => JSON.stringify(value))
  return arg.filter((value, index, self) => {
    if (typeof value === 'object')
      return stringifyedArg.indexOf(JSON.stringify(value)) === index
    return self.indexOf(value) === index
  })
}

    console.log(uniq([21, 'twenty one', 21])) // [21, 'twenty one']
    console.log(uniq([{ a: 21 }, { a: 'twenty one' }, { a: 21 }])) // [{a: 21}, {a: 'twenty one'}]

This is one of the approaches using reduce map

const arr = [{id: '1'},{id: '4'},{id: '2'},{id: '1'},{id: '3'},{id: '1'},{id: '1'},{id: '5'}]

let uniqueArr = arr.reduce((arr, item) => {
  const uniq = arr.filter(i => i.id !== item.id)
    return [...uniq, item]
  }, [])

After looking into all the 90+ answers here, I saw there is room for one more:

Array.includes has a very handy second-parameter: "fromIndex", so by using it, every iteration of the filter callback method will search the array, starting from [current index] + 1 which guarantees not to include currently filtered item in the lookup and also saves time.

_x000D_
_x000D_
//                               
var list = [0,1,2,2,3,'a','b',4,5,2,'a']

console.log( 
  list.filter((v,i) => !list.includes(v,i+1))
)

// [0,1,3,"b",4,5,2,"a"]
_x000D_
_x000D_
_x000D_

Explanation:

For example, lets assume the filter function is currently iterating at index 2) and the value at that index happens to be 2. The section of the array that is then scanned for duplicates (includes method) is everything after index 2 (i+1):

                               
[0, 1, 2,   2 ,3 ,'a', 'b', 4, 5, 2, 'a']
          |---------------------------|

And since the currently filtered item's value 2 is included in the rest of the array, it will be filtered out, because of the leading exclamation mark which negates the filter rule.


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

enter image description here

With ES5 syntax

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

Browser Compatibility: IE9+


Using filter and splice

myArray.filter((el,i)=>![...myArray].splice(0,i).includes(el))

Using Set with prototype from

Array.from(new Set(myArray))

Using Set with spread operator

[...new Set(myArray)]

Code:

function RemoveDuplicates(array) {
    return array.filter(function (value, index, self) {
        return self.indexOf(value) === index;
    });
}

Usages:

var arr = ["a","a","b","c","d", "d"];

console.log(RemoveDuplicates(arr));

Result:

0: "a"
1: "b"
2: "c"
3: "d"

Building on other answers, here's another variant that takes an optional flag to choose a strategy (keep first occurrence or keep last):

Without extending Array.prototype

function unique(arr, keepLast) {
  return arr.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
unique(['a', 1, 2, '1', 1, 3, 2, 6]); // -> ['a', 1, 2, '1', 3, 6]
unique(['a', 1, 2, '1', 1, 3, 2, 6], true); // -> ['a', '1', 1, 3, 2, 6]

Extending Array.prototype

Array.prototype.unique = function (keepLast) {
  return this.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
['a', 1, 2, '1', 1, 3, 2, 6].unique(); // -> ['a', 1, 2, '1', 3, 6]
['a', 1, 2, '1', 1, 3, 2, 6].unique(true); // -> ['a', '1', 1, 3, 2, 6]

This will work.

function getUnique(a) {
  var b = [a[0]], i, j, tmp;
  for (i = 1; i < a.length; i++) {
    tmp = 1;
    for (j = 0; j < b.length; j++) {
      if (a[i] == b[j]) {
        tmp = 0;
        break;
      }
    }
    if (tmp) {
      b.push(a[i]);
    }
  }
  return b;
}

To address the problem the other way around, it may be useful to have no duplicate while you load your array, the way Set object would do it but it's not available in all browsers yet. It saves memory and is more efficient if you need to look at its content many times.

Array.prototype.add = function (elem) {
   if (this.indexOf(elem) == -1) {
      this.push(elem);
   }
}

Sample:

set = [];
[1,3,4,1,2,1,3,3,4,1].forEach(function(x) { set.add(x); });

Gives you set = [1,3,4,2]


I know this has been answered to death already... but... no one has mentioned the javascript implementation of linq. Then the .distinct() method can be used - and it makes the code super easy to read.

var Linq = require('linq-es2015');
var distinctValues =  Linq.asEnumerable(testValues)
            .Select(x)
            .distinct()
            .toArray();

_x000D_
_x000D_
var testValues = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1];_x000D_
_x000D_
var distinctValues = Enumerable.asEnumerable(testValues)_x000D_
  .distinct()_x000D_
  .toArray();_x000D_
_x000D_
console.log(distinctValues);
_x000D_
<script src="https://npmcdn.com/linq-es5/dist/linq.js"></script>
_x000D_
_x000D_
_x000D_


This solution should be very fast, and will work in many cases.

  1. Convert the indexed array items to object keys
  2. Use Object.keys function

    var indexArray = ["hi","welcome","welcome",1,-9];
    var keyArray = {};
    indexArray.forEach(function(item){ keyArray[item]=null; });
    var uniqueArray = Object.keys(keyArray);
    

Finding unique Array values in simple method

function arrUnique(a){
  var t = [];
  for(var x = 0; x < a.length; x++){
    if(t.indexOf(a[x]) == -1)t.push(a[x]);
  }
  return t;
}
arrUnique([1,4,2,7,1,5,9,2,4,7,2]) // [1, 4, 2, 7, 5, 9]

For a array of strings:

function removeDuplicatesFromArray(arr) {
  const unique = {};
  arr.forEach((word) => {
    unique[word] = 1; // it doesn't really matter what goes here
  });
  return Object.keys(unique);
}

The version that accepts selector, should be pretty fast and concise:

function unique(xs, f) {
  var seen = {};
  return xs.filter(function(x) {
    var fx = (f && f(x)) || x;
    return !seen[fx] && (seen[fx] = 1);
  });
}

Magic

a.filter(e=>!(t[e]=e in t)) 

O(n) performance (is faster than new Set); we assume your array is in a and t={}. Explanation here (+Jeppe impr.)

_x000D_
_x000D_
let t, unique= a=> ( t={}, a.filter(e=>!(t[e]=e in t)) );

// "stand-alone" version working with global t:
// a1.filter((t={},e=>!(t[e]=e in t)));

// Test data
let a1 = [5,6,0,4,9,2,3,5,0,3,4,1,5,4,9];
let a2 = [[2, 17], [2, 17], [2, 17], [1, 12], [5, 9], [1, 12], [6, 2], [1, 12]];
let a3 = ['Mike', 'Adam','Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl'];

// Results
console.log(JSON.stringify( unique(a1) ))
console.log(JSON.stringify( unique(a2) ))
console.log(JSON.stringify( unique(a3) ))
_x000D_
_x000D_
_x000D_


Deduplication usually requires an equality operator for the given type. However, using an eq function stops us from utilizing a Set to determine duplicates in an efficient manner, because Set falls back to ===. As you know for sure, === doesn't work for reference types. So we're kind if stuck, right?

The way out is simply using a transformer function that allows us to transform a (reference) type into something we can actually lookup using a Set. We could use a hash function, for instance, or JSON.stringify the data structure, if it doesn't contain any functions.

Often we only need to access a property, which we can then compare instead of the Object's reference.

Here are two combinators that meet these requirements:

_x000D_
_x000D_
const dedupeOn = k => xs => {_x000D_
  const s = new Set();_x000D_
_x000D_
  return xs.filter(o =>_x000D_
    s.has(o[k])_x000D_
      ? null_x000D_
      : (s.add(o[k]), o[k]));_x000D_
};_x000D_
_x000D_
const dedupeBy = f => xs => {_x000D_
  const s = new Set();_x000D_
_x000D_
  return xs.filter(x => {_x000D_
    const r = f(x);_x000D_
    _x000D_
    return s.has(r)_x000D_
      ? null_x000D_
      : (s.add(r), x);_x000D_
  });_x000D_
};_x000D_
_x000D_
const xs = [{foo: "a"}, {foo: "b"}, {foo: "A"}, {foo: "b"}, {foo: "c"}];_x000D_
_x000D_
console.log(_x000D_
  dedupeOn("foo") (xs)); // [{foo: "a"}, {foo: "b"}, {foo: "A"}, {foo: "c"}]_x000D_
_x000D_
console.log(_x000D_
  dedupeBy(o => o.foo.toLowerCase()) (xs)); // [{foo: "a"}, {foo: "b"}, {foo: "c"}]
_x000D_
_x000D_
_x000D_

With these combinators we're extremely flexible in handling all kinds of deduplication issues. It's not the fastes approach, but the most expressive and most generic one.


var a = [1,4,2,7,1,5,9,2,4,7,2]
var b = {}, c = {};
var len = a.length;
for(var i=0;i<len;i++){
  a[i] in c ? delete b[a[i]] : b[a[i]] = true;
  c[a[i]] = true;
} 

// b contains all unique elements

How about using set?

   let productPrice = [230,560,125,230,678,45,230,125,127];

   let tempData = new Set(productPrice);
   let uniqeProductPrice = [...tempData];

   uniqeProductPrice.forEach((item)=>{
      console.log(item)
    });

You can use Set operator to get unique values from an array

_x000D_
_x000D_
const uniqueArray = [...new Set([1, 1, 1])];

console.log(uniqueArray) // [1]
_x000D_
_x000D_
_x000D_


This one is not pure, it will modify the array, but this is the fastest one. If yours is faster, then please write in the comments ;)

http://jsperf.com/unique-array-webdeb

Array.prototype.uniq = function(){
    for(var i = 0, l = this.length; i < l; ++i){
        var item = this[i];
        var duplicateIdx = this.indexOf(item, i + 1);
        while(duplicateIdx != -1) {
            this.splice(duplicateIdx, 1);
            duplicateIdx = this.indexOf(item, duplicateIdx);
            l--;
        }
    }

    return this;
}

[
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc"
].uniq() //  ["",2,4,"A","abc"]

I had a slightly different problem where I needed to remove objects with duplicate id properties from an array. this worked.

_x000D_
_x000D_
let objArr = [{_x000D_
  id: '123'_x000D_
}, {_x000D_
  id: '123'_x000D_
}, {_x000D_
  id: '456'_x000D_
}];_x000D_
_x000D_
objArr = objArr.reduce((acc, cur) => [_x000D_
  ...acc.filter((obj) => obj.id !== cur.id), cur_x000D_
], []);_x000D_
_x000D_
console.log(objArr);
_x000D_
_x000D_
_x000D_


A simple solution if you want to check unique values ??in an indefinite number of parameters using es6.

function uniteUnique(arr, ...rest) {
      const newArr = arr.concat(rest).flat()
      return [...new Set(newArr)]
   }

console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]))
console.log(uniteUnique([1, 2, 3], [5, 2, 1]))

I hope it will be useful to someone.


If you want to only get the unique elements and remove the elements which repeats even once, you can do this:

_x000D_
_x000D_
let array = [2, 3, 4, 1, 2, 8, 1, 1, 2, 9, 3, 5, 3, 4, 8, 4];

function removeDuplicates(inputArray) {
  let output = [];
  let countObject = {};

  for (value of array) {
    countObject[value] = (countObject[value] || 0) + 1;
  }

  for (key in countObject) {
    if (countObject[key] === 1) {
      output.push(key);
    }
  }

  return output;
}

console.log(removeDuplicates(array));
_x000D_
_x000D_
_x000D_


Sometimes I need to get unique occurrences from an array of objects. Lodash seems like a nice helper but I don't think filtering an array justifies adding a dependency to a project.

Let's assume the comparison of two objects poses on comparing a property, an id for example.

const a = [{id: 3}, {id: 4}, {id: 3}, {id: 5}, {id: 5}, {id: 5}];

Since we all love one line snippets, here is how it can be done:

a.reduce((acc, curr) => acc.find(e => e.id === curr.id) ? acc : [...acc, curr], [])


A lot of people have already mentioned using...

[...new Set(arr)];

And this is a great solution, but my preference is a solution that works with .filter. In my opinion filter is a more natural way to get unique values. You're effectively removing duplicates, and removing elements from an array is exactly what filter is meant for. It also lets you chain off of .map, .reduce and other .filter calls. I devised this solution...

const unique = () => {
  let cache;  
  return (elem, index, array) => {
    if (!cache) cache = new Set(array);
    return cache.delete(elem);
  };
};

myArray.filter(unique());

The caveat is that you need a closure, but I think this is a worthy tradeoff. In terms of performance, it is more performant than the other solutions I have seen posted that use .filter, but worse performing than [...new Set(arr)].

See also my github package youneek


Finding unique in Array of objects using One Liner

const uniqueBy = (x,f)=>Object.values(x.reduce((a,b)=>((a[f(b)]=b),a),{}));
// f -> should must return string because it will be use as key

const data = [
  { comment: "abc", forItem: 1, inModule: 1 },
  { comment: "abc", forItem: 1, inModule: 1 },
  { comment: "xyz", forItem: 1, inModule: 2 },
  { comment: "xyz", forItem: 1, inModule: 2 },
];

uniqueBy(data, (x) => x.forItem +'-'+ x.inModule); // find unique by item with module
// output
// [
//   { comment: "abc", forItem: 1, inModule: 1 },
//   { comment: "xyz", forItem: 1, inModule: 2 },
// ];

// can also use for strings and number or other primitive values

uniqueBy([1, 2, 2, 1], (v) => v); // [1, 2]
uniqueBy(["a", "b", "a"], (v) => v); // ['a', 'b']

uniqueBy(
  [
    { id: 1, name: "abc" },
    { id: 2, name: "xyz" },
    { id: 1, name: "abc" },
  ],
  (v) => v.id
);
// output
// [
//   { id: 1, name: "abc" },
//   { id: 2, name: "xyz" },
// ];

You can make use of arrays' helper functions reduce() and some() to achieve your result. Check my code snippet:

_x000D_
_x000D_
var arrayWithDuplicates = [0, 0, 1, 2, 3, 3, 4, 4, 'a', 'a', '', '', null, null];_x000D_
_x000D_
var arrayWithUniqueValues = arrayWithDuplicates_x000D_
                            .reduce((previous, item) => {_x000D_
                                if(!previous.some(element => element === item)) {_x000D_
                                    previous.push(item)_x000D_
                                }_x000D_
                                return previous;_x000D_
                            }, []);_x000D_
_x000D_
console.log('arrayWithUniqueValues', arrayWithUniqueValues)
_x000D_
_x000D_
_x000D_


Now using sets you can remove duplicates and convert them back to the array.

_x000D_
_x000D_
var names = ["Mike","Matt","Nancy", "Matt","Adam","Jenny","Nancy","Carl"];_x000D_
_x000D_
console.log([...new Set(names)])
_x000D_
_x000D_
_x000D_

Another solution is to use sort & filter

_x000D_
_x000D_
var names = ["Mike","Matt","Nancy", "Matt","Adam","Jenny","Nancy","Carl"];_x000D_
var namesSorted = names.sort();_x000D_
const result = namesSorted.filter((e, i) => namesSorted[i] != namesSorted[i+1]);_x000D_
console.log(result);
_x000D_
_x000D_
_x000D_


Many of the answers here may not be useful to beginners. If de-duping an array is difficult, will they really know about the prototype chain, or even jQuery?

In modern browsers, a clean and simple solution is to store data in a Set, which is designed to be a list of unique values.

_x000D_
_x000D_
const cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
const uniqueCars = Array.from(new Set(cars));
console.log(uniqueCars);
_x000D_
_x000D_
_x000D_

The Array.from is useful to convert the Set back to an Array so that you have easy access to all of the awesome methods (features) that arrays have. There are also other ways of doing the same thing. But you may not need Array.from at all, as Sets have plenty of useful features like forEach.

If you need to support old Internet Explorer, and thus cannot use Set, then a simple technique is to copy items over to a new array while checking beforehand if they are already in the new array.

// Create a list of cars, with duplicates.
var cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
// Create a list of unique cars, to put a car in if we haven't already.
var uniqueCars = [];

// Go through each car, one at a time.
cars.forEach(function (car) {
    // The code within the following block runs only if the
    // current car does NOT exist in the uniqueCars list
    // - a.k.a. prevent duplicates
    if (uniqueCars.indexOf(car) === -1) {
        // Since we now know we haven't seen this car before,
        // copy it to the end of the uniqueCars list.
        uniqueCars.push(car);
    }
});

To make this instantly reusable, let's put it in a function.

function deduplicate(data) {
    if (data.length > 0) {
        var result = [];

        data.forEach(function (elem) {
            if (result.indexOf(elem) === -1) {
                result.push(elem);
            }
        });

        return result;
    }
}

So to get rid of the duplicates, we would now do this.

var uniqueCars = deduplicate(cars);

The deduplicate(cars) part becomes the thing we named result when the function completes.

Just pass it the name of any array you like.


Simplest solution:

_x000D_
_x000D_
var arr = [1, 3, 4, 1, 2, 1, 3, 3, 4, 1];_x000D_
console.log([...new Set(arr)]);
_x000D_
_x000D_
_x000D_

Or:

_x000D_
_x000D_
var arr = [1, 3, 4, 1, 2, 1, 3, 3, 4, 1];_x000D_
console.log(Array.from(new Set(arr)));
_x000D_
_x000D_
_x000D_


The simplest answer is :

const array = [1, 1, 2, 2, 3, 5, 5, 2];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // [1, 2, 3, 5]

You can try this:

function removeDuplicates(arr){
  var temp = arr.sort();
  for(i = 0; i < temp.length; i++){
    if(temp[i] == temp[i + 1]){
      temp.splice(i,1);
      i--;
    }
  }
  return temp;
}

Reduce it!!!

This alternative instead of deduplicating explicitly it will take the array and reduce it so that each value of the array can be iterated and destructured in an accumulative behavior, ignoring the already included values by exploiting the persistence of the array because of the recursiveness.

['a', 1, 'a', 2, '1'].reduce((accumulator, currentValue) => accumulator.includes(currentValue) ? accumulator : [...accumulator, currentValue], [])

Test Example:

_x000D_
_x000D_
var array = ['a', 1, 'a', 2, '1'];_x000D_
const reducer = (accumulator, currentValue) => accumulator.includes(currentValue) ? accumulator : [...accumulator, currentValue];_x000D_
_x000D_
console.log(_x000D_
  array.reduce(reducer, [])_x000D_
);
_x000D_
_x000D_
_x000D_

Conclusion

By far more elegant and useful when boring for-each approach wants to be avoided (not that it is not useful).

No need for external libraries like Underscore.js, JQuery or Lo-Dash, nor the trouble to create any built-in function to achieve the desired deduplicated effect.

Oh, and HEY!, it can be done as a one-liner!!!


This answered was possible thanks to ES5 (ECMAScript 2015) include() and reduce().


The task is to get a unique array from an array consisted of arbitrary types (primitive and non primitive).

The approach based on using new Map(...) is not new. Here it is leveraged by JSON.stringify(...), JSON.parse(...) and [].map method. The advantages are universality (applicability for an array of any types), short ES6 notation and probably performance for this case:

_x000D_
_x000D_
const dedupExample = [
    { a: 1 },
    { a: 1 },
    [ 1, 2 ],
    [ 1, 2 ],
    1,
    1,
    '1',
    '1'
]

const getUniqArr = arr => {
    const arrStr = arr.map(item => JSON.stringify(item))
    return [...new Set(arrStr)]
        .map(item => JSON.parse(item))
}

console.info(getUniqArr(dedupExample))
   /* [ {a: 1}, [1, 2], 1, '1' ] */
_x000D_
_x000D_
_x000D_


pure js in one single line:

const uniqueArray = myArray.filter((elem, pos) => myArray.indexOf(elem) == pos); 

Found this sweet snippet from a post by Changhui Xu for those looking to get unique objects. I haven't measured its performance against the other alternatives though.

_x000D_
_x000D_
const array = [{_x000D_
    name: 'Joe',_x000D_
    age: 17_x000D_
  },_x000D_
  {_x000D_
    name: 'Bob',_x000D_
    age: 17_x000D_
  },_x000D_
  {_x000D_
    name: 'Tom',_x000D_
    age: 25_x000D_
  },_x000D_
  {_x000D_
    name: 'John',_x000D_
    age: 22_x000D_
  },_x000D_
  {_x000D_
    name: 'Jane',_x000D_
    age: 20_x000D_
  },_x000D_
];_x000D_
_x000D_
const distinctAges = [...new Set(array.map(a => a.age))];_x000D_
_x000D_
console.log(distinctAges)
_x000D_
_x000D_
_x000D_


I split all answers to 4 possible solutions:

  1. Use object { } to prevent duplicates
  2. Use helper array [ ]
  3. Use filter + indexOf
  4. Bonus! ES6 Sets method.

Here's sample codes found in answers:

Use object { } to prevent duplicates

function uniqueArray1( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });

  return Object.keys(j).map(function(v){
    return j[v];
  });
} 

Use helper array [ ]

function uniqueArray2(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

Use filter + indexOf

function uniqueArray3(a) {
  function onlyUnique(value, index, self) { 
      return self.indexOf(value) === index;
  }

  // usage
  var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

  return unique;
}

Use ES6 [...new Set(a)]

function uniqueArray4(a) {
  return [...new Set(a)];
}

And I wondered which one is faster. I've made sample Google Sheet to test functions. Note: ECMA 6 is not avaliable in Google Sheets, so I can't test it.

Here's the result of tests: enter image description here

I expected to see that code using object { } will win because it uses hash. So I'm glad that tests showed the best results for this algorithm in Chrome and IE. Thanks to @rab for the code.

Update 2020

Google Script enabled ES6 Engine. Now I tested the last code with Sets and it appeared faster than the object method.


Yet another answer, just because I wrote one for my specific use case. I happened to be sorting the array anyway, and given I'm sorting I can use that to deduplicate.

Note that my sort deals with my specific data types, you might need a different sort depending on what sort of elements you have.

var sortAndDedup = function(array) {
  array.sort(function(a,b){
    if(isNaN(a) && isNaN(b)) { return a > b ? 1 : (a < b ? -1 : 0); }
    if(isNaN(a)) { return 1; }
    if(isNaN(b)) { return -1; }
    return a-b;
  });

  var newArray = [];
  var len = array.length;
  for(var i=0; i<len; i++){
    if(i === 0 || array[i] != array[i-1]){
      newArray.push(array[i]);
    }
  }
};

I'm not sure why Gabriel Silveira wrote the function that way but a simpler form that works for me just as well and without the minification is:

Array.prototype.unique = function() {
  return this.filter(function(value, index, array) {
    return array.indexOf(value, index + 1) < 0;
  });
};

or in CoffeeScript:

Array.prototype.unique = ->
  this.filter( (value, index, array) ->
    array.indexOf(value, index + 1) < 0
  )

If you're okay with extra dependencies, or you already have one of the libraries in your codebase, you can remove duplicates from an array in place using LoDash (or Underscore).

Usage

If you don't have it in your codebase already, install it using npm:

npm install lodash

Then use it as follows:

import _ from 'lodash';
let idArray = _.uniq ([
    1,
    2,
    3,
    3,
    3
]);
console.dir(idArray);

Out:

[ 1, 2, 3 ]

_x000D_
_x000D_
(function() {_x000D_
    "use strict";_x000D_
_x000D_
    Array.prototype.unique = function unique() {_x000D_
        var self = this;_x000D_
        return self.filter(function(a) {_x000D_
            var that = this;_x000D_
            // console.log(that);_x000D_
            return !that[a] ? that[a] = true : false;_x000D_
        }, {});_x000D_
    }_x000D_
_x000D_
    var sampleArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];_x000D_
    var distinctArray = sampleArray.unique();_x000D_
    console.log(distinctArray);_x000D_
})();
_x000D_
Here is the simple way to solve this problem...
_x000D_
_x000D_
_x000D_


strange this hasn't been suggested before.. to remove duplicates by object key (id below) in an array you can do something like this:

const uniqArray = array.filter((obj, idx, arr) => (
  arr.findIndex((o) => o.id === obj.id) === idx
)) 

Look at this. Jquery provides uniq method: https://api.jquery.com/jQuery.unique/

var ids_array = []

$.each($(my_elements), function(index, el) {
    var id = $(this).attr("id")
    ids_array.push(id)
});

var clean_ids_array = jQuery.unique(ids_array)

$.each(clean_ids_array, function(index, id) {
   elment = $("#" + id)   // my uniq element
   // TODO WITH MY ELEMENT
});

["Defects", "Total", "Days", "City", "Defects"].reduce(function(prev, cur) {
  return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
 }, []);

[0,1,2,0,3,2,1,5].reduce(function(prev, cur) {
  return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
 }, []);

This is an ES6 function which removes duplicates from an array of objects, filtering by the specified object property

function dedupe(arr = [], fnCheck = _ => _) {
  const set = new Set();
  let len = arr.length;

  for (let i = 0; i < len; i++) {
    const primitive = fnCheck(arr[i]);
    if (set.has(primitive)) {
      // duplicate, cut it
      arr.splice(i, 1);
      i--;
      len--;
    } else {
      // new item, add it
      set.add(primitive);
    }
  }

  return arr;
}

const test = [
    {video:{slug: "a"}},
    {video:{slug: "a"}},
    {video:{slug: "b"}},
    {video:{slug: "c"}},
    {video:{slug: "c"}}
]
console.log(dedupe(test, x => x.video.slug));

// [{video:{slug: "a"}}, {video:{slug: "b"}}, {video:{slug: "c"}}]

This script modify the array, filtering out duplicated values. It works with numbers and strings.

https://jsfiddle.net/qsdL6y5j/1/

    Array.prototype.getUnique = function () {
        var unique = this.filter(function (elem, pos) {
            return this.indexOf(elem) == pos;
        }.bind(this));
        this.length = 0;
        this.splice(0, 0, unique);
    }

    var duplicates = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    duplicates.getUnique();
    alert(duplicates);

This version instead, allow you to return a new array with unique value keeping the original (just pass true).

https://jsfiddle.net/dj7qxyL7/

    Array.prototype.getUnique = function (createArray) {
        createArray = createArray === true ? true : false;
        var temp = JSON.stringify(this);
        temp = JSON.parse(temp);
        if (createArray) {
            var unique = temp.filter(function (elem, pos) {
                return temp.indexOf(elem) == pos;
            }.bind(this));
            return unique;
        }
        else {
            var unique = this.filter(function (elem, pos) {
                return this.indexOf(elem) == pos;
            }.bind(this));
            this.length = 0;
            this.splice(0, 0, unique);
        }
    }

    var duplicates = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    console.log('++++ ovveride')
    duplicates.getUnique();
    console.log(duplicates);
    console.log('++++ new array')
    var duplicates2 = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    var unique = duplicates2.getUnique(true);
    console.log(unique);
    console.log('++++ original')
    console.log(duplicates2);

Browser support:

Feature Chrome  Firefox (Gecko)     Internet Explorer   Opera   Safari
Basic support   (Yes)   1.5 (1.8)   9                   (Yes)   (Yes)

[...new Set(duplicates)]

This is the simplest one and referenced from MDN Web Docs.

const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
console.log([...new Set(numbers)]) // [2, 3, 4, 5, 6, 7, 32]

The Object answer above does not seem to work for me in my use case with Objects.

I have modified it as follows:

var j = {};

this.forEach( function(v) {
   var typ = 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];
});

This seems to now work correctly for objects, arrays, arrays with mixed values, booleans, etc.


Here is an almost one-liner that is O(n), keeps the first element, and where you can keep the field you are uniq'ing on separate.

This is a pretty common technique in functional programming - you use reduce to build up an array that you return. Since we build the array like this, we guarantee that we get a stable ordering, unlike the [...new Set(array)] approach. We still use a Set to ensure we don't have duplicates, so our accumulator contains both a Set and the array we are building.

_x000D_
_x000D_
const removeDuplicates = (arr) =>
  arr.reduce(
    ([set, acc], item) => set.has(item) ? [set, acc] : [set.add(item), (acc.push(item), acc)],
    [new Set(), []]
  )[1]
_x000D_
_x000D_
_x000D_

The above will work for simple values, but not for objects, similarly to how [...new Set(array)] breaks down. If the items are objects that contain an id property, you'd do:

_x000D_
_x000D_
const removeDuplicates = (arr) =>
  arr.reduce(
    ([set, acc], item) => set.has(item.id) ? [set, acc] : [set.add(item.id), (acc.push(item), acc)],
    [new Set(), []]
  )[1]
_x000D_
_x000D_
_x000D_


If anyone using knockoutjs

ko.utils.arrayGetDistinctValues()

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


The simplest, and fastest (in Chrome) way of doing this:

Array.prototype.unique = function() {
    var a = [];
    for (var i=0, l=this.length; i<l; i++)
        if (a.indexOf(this[i]) === -1)
            a.push(this[i]);
    return a;
}

Simply goes through every item in the array, tests if that item is already in the list, and if it's not, push to the array that gets returned.

According to jsPerf, this function is the fastest of the ones I could find anywhere - feel free to add your own though.

The non-prototype version:

function uniques(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

Sorting

When also needing to sort the array, the following is the fastest:

Array.prototype.sortUnique = function() {
    this.sort();
    var last_i;
    for (var i=0;i<this.length;i++)
        if ((last_i = this.lastIndexOf(this[i])) !== i)
            this.splice(i+1, last_i-i);
    return this;
}

or non-prototype:

function sortUnique(arr) {
    arr.sort();
    var last_i;
    for (var i=0;i<arr.length;i++)
        if ((last_i = arr.lastIndexOf(arr[i])) !== i)
            arr.splice(i+1, last_i-i);
    return arr;
}

This is also faster than the above method in most non-chrome browsers.


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 arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to duplicates

Remove duplicates from dataframe, based on two columns A,B, keeping row with max value in another column C Remove duplicates from a dataframe in PySpark How to "select distinct" across multiple data frame columns in pandas? How to find duplicate records in PostgreSQL Drop all duplicate rows across multiple columns in Python Pandas Left Join without duplicate rows from left table Finding duplicate integers in an array and display how many times they occurred How do I use SELECT GROUP BY in DataTable.Select(Expression)? How to delete duplicate rows in SQL Server? Python copy files to a new directory and rename if file name already exists

Examples related to set

java, get set methods golang why don't we have a set datastructure Simplest way to merge ES6 Maps/Sets? Swift Set to Array JavaScript Array to Set How to sort a HashSet? Python Set Comprehension How to get first item from a java.util.Set? Getting the difference between two sets Python convert set to string and vice versa

Examples related to unique

Count unique values with pandas per groups Find the unique values in a column and then sort them How can I check if the array of objects have duplicate property values? Firebase: how to generate a unique numeric ID for key? pandas unique values multiple columns Select unique values with 'select' function in 'dplyr' library Generate 'n' unique random numbers within a range SQL - select distinct only on one column Can I use VARCHAR as the PRIMARY KEY? Count unique values in a column in Excel