Categories
arrays duplicates javascript jquery unique

Remove duplicate values from JS array [duplicate]

2075

I have a very simple JavaScript array that may or may not contain duplicates.

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

I need to remove the duplicates and put the unique values in a new array.

I could point to all the codes that I’ve tried but I think it’s useless because they don’t work. I accept jQuery solutions too.

Similar question:

13

  • 89

    _.uniq(peoplenames) solves this lodash.com/docs#uniq

    Jul 29, 2014 at 19:29


  • 10

    @ConnorLeech its easy with lodash but not optimized way

    May 16, 2017 at 10:35

  • 42

    The simplest approach (in my opinion) is to use the Set object which lets you store unique values of any type. In other words, Set will automatically remove duplicates for us. const names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"]; let unique = [...new Set(names)]; console.log(unique); // 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl'

    – Asif vora

    Dec 10, 2018 at 10:43

  • 11

    There are too many Mikes in the world – why not remove them? Nancy got owned on this.

    – toad

    Feb 9, 2019 at 2:47

  • 2

    in my solution, I sort data before filtering : ` const result = data.sort().filter((v, idx, t) => idx==0 || v != t[idx-1]);

    – Didier68

    Jul 2, 2020 at 9:06


509

Quick and dirty using jQuery:

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
var uniqueNames = [];
$.each(names, function(i, el){
    if($.inArray(el, uniqueNames) === -1) uniqueNames.push(el);
});

11

  • 362

    wouldn’t mind a non-jquery answer for those who don’t use it

    – Matej

    Apr 11, 2017 at 18:08

  • 8

    As this was reverted back to the original inArray solution by a reputable person, I am going to again mention: this solution is O(n^2), making it inefficient.

    Sep 21, 2017 at 16:35

  • 40

    I really wish in 2020 we could start depreciating jQuery and other even-more dated answers… Stackoverflow is starting to show some age here…

    Jun 29, 2020 at 23:23

  • 6

    I agree @NickSteele but I find it does happen naturally over time if you look at votes and not the accepted answer. The best answer will gravitate towards the top as older deprecated answers get downvoted

    – Chris

    Sep 30, 2020 at 7:25

  • 1

    let uniqueNames = names.filter((item, pos ,self) => self.indexOf(item) == pos);

    Nov 17, 2020 at 20:04

509

Quick and dirty using jQuery:

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
var uniqueNames = [];
$.each(names, function(i, el){
    if($.inArray(el, uniqueNames) === -1) uniqueNames.push(el);
});

11

  • 362

    wouldn’t mind a non-jquery answer for those who don’t use it

    – Matej

    Apr 11, 2017 at 18:08

  • 8

    As this was reverted back to the original inArray solution by a reputable person, I am going to again mention: this solution is O(n^2), making it inefficient.

    Sep 21, 2017 at 16:35

  • 40

    I really wish in 2020 we could start depreciating jQuery and other even-more dated answers… Stackoverflow is starting to show some age here…

    Jun 29, 2020 at 23:23

  • 6

    I agree @NickSteele but I find it does happen naturally over time if you look at votes and not the accepted answer. The best answer will gravitate towards the top as older deprecated answers get downvoted

    – Chris

    Sep 30, 2020 at 7:25

  • 1

    let uniqueNames = names.filter((item, pos ,self) => self.indexOf(item) == pos);

    Nov 17, 2020 at 20:04

378

Got tired of seeing all bad examples with for-loops or jQuery. Javascript has the perfect tools for this nowadays: sort, map and reduce.

Uniq reduce while keeping existing order

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

var uniq = names.reduce(function(a,b){
    if (a.indexOf(b) < 0 ) a.push(b);
    return a;
  },[]);

console.log(uniq, names) // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]

// one liner
return names.reduce(function(a,b){if(a.indexOf(b)<0)a.push(b);return a;},[]);

Faster uniq with sorting

There are probably faster ways but this one is pretty decent.

var uniq = names.slice() // slice makes copy of array before sorting it
  .sort(function(a,b){
    return a > b;
  })
  .reduce(function(a,b){
    if (a.slice(-1)[0] !== b) a.push(b); // slice(-1)[0] means last item in array without removing it (like .pop())
    return a;
  },[]); // this empty array becomes the starting value for a

// one liner
return names.slice().sort(function(a,b){return a > b}).reduce(function(a,b){if (a.slice(-1)[0] !== b) a.push(b);return a;},[]);

Update 2015: ES6 version:

In ES6 you have Sets and Spread which makes it very easy and performant to remove all duplicates:

var uniq = [ ...new Set(names) ]; // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]

Sort based on occurrence:

Someone asked about ordering the results based on how many unique names there are:

var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

var uniq = names
  .map((name) => {
    return {count: 1, name: name}
  })
  .reduce((a, b) => {
    a[b.name] = (a[b.name] || 0) + b.count
    return a
  }, {})

var sorted = Object.keys(uniq).sort((a, b) => uniq[a] < uniq[b])

console.log(sorted)

11

  • Nice! Would it be possible to sort the array based on the frequency of duplicate objects? So that "Nancy" in the above example is moved to the front (or back) of the modified array?

    – ALx

    Nov 25, 2015 at 13:38

  • @ALx – I updated with an example for sorting based on occurrence.

    Dec 2, 2015 at 22:21

  • sort() appears to be called incorrectly in your second example: if a is < b then it returns the same value as if a == b, which can lead to unsorted results. Unless you’re doing something clever here that I’m missing, should be .sort(function(a,b){ return a > b ? 1 : a < b ? -1 : 0; })

    – Shog9

    Feb 5, 2016 at 1:51

  • If the data is just an array of names with no requirement other than to eliminate duplicates, why bother with sort, map, and reduce? Just use a set – job done in O(n) time. — msdn.microsoft.com/en-us/library/dn251547

    – Dave

    May 19, 2016 at 16:47


  • @Dave yes- see my example on [...new Set(names)] above

    May 24, 2016 at 14:59