I have a class called Thing
. For simplicity, let's say it initializes with a unique id, and that's all that's unique about it:
class Thing {
id: string;
constructor(id: string) {
this.id = id;
}
}
Based on its id
, a Thing
will reference a specific item in the underlying database. It is essentially an abstraction class to help interact with data.
I have a helper class to manage the Thing
s:
class AllTheThings {
existingThings: Set<Thing> = new Set();
createThing(id: string){
const newThing = new Thing(id)
this.existingThings.add(newThing)
}
}
Throughout a certain cycle in the code, createThing
is called with a variety of id
s. That cycle repeats, and createThing
may be called again with the same id
s from the last cycle. That is fine. But at the start of any cycle, I need to have a list of the unique Thing
s that already have been created in the past.
I need a way to keep a list of unique Thing
s which have been created so far. I initially thought of using a Set
, as above. However, due to the repetition, and the fact that I am adding a class instance to a set, the entries repeat. For example:
// cycle1:
AllTheThings.createThing(1)
AllTheThings.createThing(2)
// cycle2:
AllTheThings.createThing(2)
AllTheThings.createThing(3)
My intention at the end of cycle2 is that I would have 3 unique items in the existingThings
Set. But I end up with 4. For those not familiar with Set
, this is because new Thing(1) !== new Thing(1)
. While the resulting objects are identical, they are not the same, and they point to different references in memory. I get that.
But the problem remains that I need a list of unique Thing
s that have been created in the past. I am considering doing the following:
class AllTheThings {
existingThings: Set<string> = new Set();
createThing(id: string){
const newThing = new Thing(id)
this.existingThings.add(id)
}
}
So in this case, I am keeping a list of unique id
s, and I won't get the same type of repetition as before. However, I really need a list of unique Thing
s, not Thing
ids. In reality the code is more complex, and a new Thing
takes more arguments than just an id
. While those arguments are available when calling createThing
, they may not be available when accessing existingThings
, which means I cannot easily recreate a Thing
just from an id
where existingThings
is used - I need the whole Thing
. I can go the route of using a Set
of id
s, but it would require a lot of refactoring.
Is there a more concise way to maintain a list of unique objects/class instances in a Set
?
1 Answer 1
One possible workaround could be to use a Map
rather than a Set
. That way you can store Thing
s by their IDs (which we already know uniquely identify them) and then use those IDs to unambiguously get the Thing
back later
Admittedly, this does carry the risk that the IDs get out of sync and the Map
ends up associating a Thing
with the wrong ID, but it doesn't sound like Thing
s' IDs are meant to change over their lifetimes, in which case it should be safe
-
1\$\begingroup\$ Interesting...I think this is a nice compromise. I can say
existingThings: Map<string, Thing> = new Map()
, then I can saythis.existingThings.set(newThing.id, newThing)
. Even when that same Thing is created with the same id, it will call.set
again, but it won't duplicate, it will just overwrite, which I think will be fine. I will try this, thank you! \$\endgroup\$Seth Lutske– Seth Lutske2021年06月01日 17:58:57 +00:00Commented Jun 1, 2021 at 17:58
Explore related questions
See similar questions with these tags.