5

I have an array of objects:

[
  { id: 1, name: "Bob" },
  { id: 1, name: "Donald" },
  { id: 2, name: "Daryl" }
]

I'd like to strip out objects with duplicate Ids, leaving an array that would look like this:

[
  { id: 1, name: "Bob" },
  { id: 2, name: "Daryl" }
]

I don't care which objects are left, as long as each ID is unique. Anything in Underscore, maybe, that would do this?

Edit: This is not the same as the duplicate listed below; I'm not trying to filter duplicate OBJECTS, but objects that contain identical IDs. I've done this using Underscore - I'll post the answer shortly.

opticon
  • 3,494
  • 5
  • 37
  • 61
  • 1
    possible duplicate of [Remove duplicates from an array of objects in javascript](http://stackoverflow.com/questions/2218999/remove-duplicates-from-an-array-of-objects-in-javascript) – Marcos Pérez Gude Sep 17 '15 at 15:52

6 Answers6

9

You can use reduce and some to good effect here:

var out = arr.reduce(function (p, c) {

  // if the next object's id is not found in the output array
  // push the object into the output array
  if (!p.some(function (el) { return el.id === c.id; })) p.push(c);
  return p;
}, []);

DEMO

Andy
  • 61,948
  • 13
  • 68
  • 95
4

the es6 way

function removeDuplicates(myArr, prop) {
    return myArr.filter((obj, pos, arr) => {
        return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos
    })
}

Test it

let a =[
      { id: 1, name: "Bob" },
      { id: 1, name: "Donald" },
      { id: 2, name: "Daryl" }
    ]

    console.log( removeDuplicates( a, 'id' ) )

    //output [
      { id: 1, name: "Bob" },
      { id: 2, name: "Daryl" }
    ]
angry kiwi
  • 10,730
  • 26
  • 115
  • 161
1

If you use underscore, you can use the _uniq method

var data = [
    { id: 1, name: "Bob" },
    { id: 1, name: "Donald" },
    { id: 2, name: "Daryl" }
]

_.uniq(data, function(d){ return d.ID });

Produces a duplicate-free version of the array, using === to test object equality. In particular only the first occurence of each value is kept. If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iteratee function.

Source: http://underscorejs.org/#uniq

Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87
1

Can use es6 Map collection mix with reduce

const items = [
    { id: 1, name: "Bob" },
    { id: 1, name: "Donald" },
    { id: 2, name: "Daryl" }
]

const uniqItems = [...items.reduce((itemsMap, item) =>                                                                   
      itemsMap.has(item.id) ? itemsMap : itemsMap.set(item.id, item)
    , new Map()).values()]

console.log(uniqItems);
Nader
  • 933
  • 1
  • 7
  • 8
1

Using findIndex should be the simplest solution.

array.filter((elem, index, arr) => arr.findIndex(e => e.id === elem.id) === index) 
0

You can simply filter the array, but you'll need an index of existing IDs that you've already used...

    var ids = [];
    var ar = [
        { id: 1, name: "Bob" },
        { id: 1, name: "Donald" },
        { id: 2, name: "Daryl" }
    ];
    ar = ar.filter(function(o) {
        if (ids.indexOf(o.id) !== -1) return false;
        ids.push(o.id);
        return true;
    });
    console.log(ar);

Here's some documentation on filter()...

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Reinstate Monica Cellio
  • 25,975
  • 6
  • 51
  • 67
  • @Michal Perhaps you'd care to explain what you mean. I'd really like to know why this is "bad practice". – Reinstate Monica Cellio May 07 '18 at 17:35
  • Your example is based on imperative programming. Functional programming might be a little bit harder to understand but is definitely the right way to go. – Michal May 08 '18 at 19:03
  • @Michal I'm not sure why you think "Functional programming" is harder to understand, but regardless, that's not relevant. You can't actually explain why you call this bad practice, because there is literally *nothing* wrong with it. If you just want to express a preference over a different method then that's perfectly normal, but think carefully about your words. This answer is not bad practice - 100% fact. – Reinstate Monica Cellio May 08 '18 at 20:01