In JavaScript two objects are different if they are not the same reference, even when they look the same:
var a = {};
var b = {};
console.log(a === b); // false
b = a;
console.log(a === b); // true
Sets work similarly: unless objects added to it are referring to the same thing, they will be distinct.
A Custom Set
One idea to make it work like you want, is to create your own flavour of Set, i.e. MySet, giving it all the methods and properties you need for it to work as a Set.
Then in its implementation you would keep a Map in its internals, where you give a key to everything you store in it. You could then make sure that objects that you consider the same, get the same key in that map, and so are only stored once.
A non-efficient, but straightforward way of doing that, is to use JSON.stringify(item) as key. This has its limitations (e.g. adding self-referencing objects will make JSON.stringify(item) give up), but for the rest it does the job.
We could make MySet to accept an additional argument: the function to invoke to get an item's key value. Given the above idea, we would give it the default value JSON.stringify.
Consider this implementation, with your testing code added to it:
// Implementation of special Set:
class MySet {
constructor(values = [], keyFunc = JSON.stringify) {
// Use a map to store the values
this._map = new Map();
// Which function to use for generating an item's key
this._keyFunc = keyFunc;
// Add the initial values
for (var value of [...values]) this.add(value);
}
get size() {
return this._map.size;
}
add(item) {
// Key items by the given function
this._map.set(this._keyFunc(item), item);
}
has(item) {
return this._map.has(this._keyFunc(item));
}
*[Symbol.iterator] () {
for (var pair of this._map) {
yield pair[1]; // return the item
}
}
// etc...
}
// Test it:
array = [{n:"J",last:"B"}, {n:"J",last:"B"}];
out = [...new MySet(array)];
console.log(out);
As you can see, although two objects were added to the set, it has only stored one.
Setwill work fine for objects as well. However, in your case you have two different objects, even though they have the same properties (and values). You have define your own logic to compare and filter such arrays.Setdoes not support custom comparators. So, If you don't want to reinvent the wheel, you'll have to use something like Lodash'suniqueBySetdoesn't work like that.