I am trying to use ES6 from TypeScript via lib.es6.d.ts. I need to understand how to enforce equality comparison and sameness for an object for use in a Set<T>
. For example, the object looks like the following.
class Product {
metadata: Map<String, String>
constructor(id: number) {
metadata = new Map<String, String>();
}
public addMetadata(key: String, val: String): Product {
this.metadata.set(key, val);
return this;
}
}
Note that id
field value in Product
is what determines its uniqueness. If two Product instances have the same id, they are considered the same in my application, even if the metadata
differs. In general, I only want only a subset of the fields to be used as a part of testing for equality and sameness.
In Java, we override the equals
method to control and test for sameness. In JavaScript, what do we need to do to determine sameness?
The link on MDN states the following:
Because each value in the Set has to be unique, the value equality will be checked.
I assume by value equality they mean ===
? Again, MDN shows 4 equality algorithms in ES2015 alone.
Basically, in my class above, I want to do something like the following.
let p1 = new Product(1);
let p2 = new Product(2);
let p3 = new Product(1); //duplicate of p1 by id
p1.addMetadata('k1','v1').addMetadata('k2','v2');
p2.addMetadata('k1','v1');
let mySet = new Set<Product>();
mySet.add(p1);
mySet.add(p2);
mySet.add(p3);
assertEquals(2, mySet.size); //some assertion method
A
Set
orMap
considers a key that is an object to be the same only if it is exactly the same object, not a different object with the same content, but the same actual object. In other words, it works just likeobj1 === obj2
.If you're using a
Set
like your title and first paragraph refer to, then you're pretty much out of luck. Two separate objects that the same contents (or in your case, the same.id
property) will be considered separate items in theSet
because they are actually different objects.You can see in this question How to customize object equality for JavaScript Set a discussion about whether this is customizable for a
Set
or not (it's not).If you're using a
Map
(which appears to be what your code refers to, even though that's not what the text of your question says), then you could use the.id
property as the key and the object itself as the value. As long as the.id
property is a primitive (like a string or a number), then you will only get one item in theMap
for any givenid
.