Coffeescript / Node.js: How to remove duplicate objects from an array of objects?

How can I turn this array of objects (which has some duplicate objects):

items =
  [
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Silver' },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Yellow' },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Blue'   },
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Black'  },
    { TYPEID: 1248350, NAME: 'Staples',    COLOR: 'Black'  },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Blue'   },
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Silver' },
    { TYPEID: 150927,  NAME: 'Fasteners',  COLOR: 'Silver' }
  ]

Into this:

items =
  [
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Silver' },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Yellow' },
    { TYPEID: 1246007, NAME: 'Pencils',    COLOR: 'Blue'   },
    { TYPEID: 150927,  NAME: 'Staples',    COLOR: 'Black'  },
    { TYPEID: 1248350, NAME: 'Staples',    COLOR: 'Black'  },
    { TYPEID: 150927,  NAME: 'Fasteners',  COLOR: 'Silver' }
  ]

...by filtering out the two duplicate objects (the silver staples and the blue pencils)?

It seems like there should be an easy way to do this, but I've yet to find a simple solution.

I've seen some javascript / jquery code which does this, but I'm not the best at converting those into coffeescript.

UPDATE:

There will often be different objects with the very similar properties.

In the actual application, each object has a potential of 25 properties.

I only want to remove objects if each of those properties are equal.

UPDATE 2

This is the code that ended up working for me - (thanks to rjz)

unique = (objAry, callback) ->
  results = []

  valMatch = (seen, obj) ->
    for other in seen
      match = true
      for key, val of obj
        match = false unless other[key] == val
      return true if match
    false

  objAry.forEach (item) ->
    unless valMatch(results, item)
      results.push(item)
  callback null, results

And this is how I'll call it:

unique items, (err, items) ->
  console.log items

Depending how deeply you want to check equality, you could probably just assume uniqueness of the USERID field and do something like this:

ids = []    # Contains list of "seen" IDs
result = [] # Contains list of unique users

users.forEach (u) -> 
  if result.indexOf(u.USERID) == -1
    result.push(u)
    ids.push(u.USERID)

If you need to do deeper matching and don't have a primary key available (might be a sign of bigger issues), you could create a more sophisticated test for equality:

valMatch = (seen, obj) ->
  for other in seen
    match = true
    for key, val of obj
      match = false unless other[key] == val
    return true if match
  false

result = []
seen = []

data.forEach (datum) -> 
  unless valMatch(result, datum)
    result.push(datum)
    seen.push(datum)

I would use underscore.js and try something like this

result = item[0] for item in _.groupBy(users, (user) => user.USERID)

Its not tested thou ;-) obviously this assumes that we only check for the USERID

if you can't only check for the USERID you could of course transform all objects into json-strings and then compare the json strings

result = item[0] for item in _.groupBy(users, (user) => user.toJSON())

obviously this is a dirty hack that will rely on the fact that all browsers and engines serialize objects and their slots in the order of creation/assignment.

So in any way rjz's solution is certainly the better one but this will most likely work as well.