C
C#2y ago
Birdman

❔ Best way to create a unique key made out of x y integer coordonates for a dictionary

Hello, i want to create a unique key to access values in a Dictionary, this key has to be unique and able to be created using just simple x y integer type coordonates. Any help is appreciated. Thank you
47 Replies
sibber
sibber2y ago
why not make TKey the coordinate
Birdman
BirdmanOP2y ago
not sure i follow
sibber
sibber2y ago
Dictionary<Coordinate, Whatever>
Birdman
BirdmanOP2y ago
but let's say i make a Coordonate(1, 2) and then create a new Coordonate(1, 2) object to access that value, would it work?
sibber
sibber2y ago
if they return the same hash code then yes
Birdman
BirdmanOP2y ago
but would they retun the same hash code? like if i do Coordonate(1, 2) Coordonate(1, 2) would both have same hash?
sibber
sibber2y ago
i mean you should override GetHashCode
ero
ero2y ago
If you implement the method, sure
sibber
sibber2y ago
or preferably make it a record
ero
ero2y ago
Definitely make it a record A ValueTuple might just be enough But less concrete
Birdman
BirdmanOP2y ago
but don't i have to manually generate the hash myself to always get a unique one based on the coordonates?
sibber
sibber2y ago
GetHashCode is a method from object you just override it in the class/struct or use a record which does it for you, as well as implementing value equality and other things
Birdman
BirdmanOP2y ago
okay sure, i get that, but my issue is how do i generate that hash so it's unique but also recreatable from the coordonates
D.Mentia
D.Mentia2y ago
also if it's a struct you're already done; as long as the values match it's equal
sibber
sibber2y ago
you dont, Dictionary does
ero
ero2y ago
The whole point is that it is recreatable You implement the creation
D.Mentia
D.Mentia2y ago
Hashcodes are kindof a whole separate thing that you don't really need to know anymore because of records Just use a struct, or a record, and it'll do the job
sibber
sibber2y ago
not exactly
D.Mentia
D.Mentia2y ago
? That's how value types work, right? And structs are always value types?
ero
ero2y ago
Only if they're unmanaged As in, fit the unmanaged constraint If the struct contains a reference type, it won't work
D.Mentia
D.Mentia2y ago
Oh yeah, that's fair
MODiX
MODiX2y ago
Cyberrex#8052
REPL Result: Success
S s1 = new() { Y = "a" };
S s2 = new() { Y = "b" };
Console.WriteLine(s1.GetHashCode() == s2.GetHashCode());

struct S
{
public int X {get;set;}
public string Y { get; set; }
}
S s1 = new() { Y = "a" };
S s2 = new() { Y = "b" };
Console.WriteLine(s1.GetHashCode() == s2.GetHashCode());

struct S
{
public int X {get;set;}
public string Y { get; set; }
}
Console Output
True
True
Compile: 462.573ms | Execution: 68.553ms | React with ❌ to remove this embed.
ero
ero2y ago
String is the exception of course
D.Mentia
D.Mentia2y ago
Though I think the real answer to this question is, don't use a Dictionary, use a 2d array. There's no advantage to using a Dictionary for this, I don't think? Since there is a known lower and upper bound, and it's already integers, the 2d array lookup would be just as fast as a dictionary (or faster, since you're not making a Coordinate)
sibber
sibber2y ago
not really, it depends on what theyre trying to do
D.Mentia
D.Mentia2y ago
(a 2d array also means you could do things like, binary search to find the entity that is closest to a given coordinate...? Maybe. I've been thinking about a similar implementation)
Birdman
BirdmanOP2y ago
hmm, how much slower would be iterating through a 100000x100000 array vs a dictionary with a much smaller list of coordonates?
sibber
sibber2y ago
how are they an exception in this case?
Birdman
BirdmanOP2y ago
cause i have to iterate through the whole thing
sibber
sibber2y ago
probably faster than a dictionary
D.Mentia
D.Mentia2y ago
I've been told you should never iterate a dictionary, but I don't know how bad it is if you do
sibber
sibber2y ago
oh wait smaller? depends, benchmark it i mean yeah a dictionary isnt meant to be iterated
D.Mentia
D.Mentia2y ago
If you're iterating it, why do you need to be able to lookup the value?
sibber
sibber2y ago
iterating it will be relatively slow
Birdman
BirdmanOP2y ago
huge mostly empty array vs a dictionary with lets say 20% of the values in the 2d array to remove values from it and also add
sibber
sibber2y ago
i think having a coordinate type and a dictionary makes more sense
Birdman
BirdmanOP2y ago
and also build something from it, that's why i have to iterate through all of it
sibber
sibber2y ago
still why do you need to iterate it?
ero
ero2y ago
String already implements Equals and GetHashCode
sibber
sibber2y ago
yeah but the default struct.GetHashCode doesnt use that
D.Mentia
D.Mentia2y ago
Then a HashSet is probably your best bet; constant time add/remove/contains, iteration is fine. That's the point where you need to make sure what you're storing has good Equals and GetHashCode implementations for a HashSet
sibber
sibber2y ago
this might be an xy problem
D.Mentia
D.Mentia2y ago
... well, idk. Dictionary is fine. The other answers are fine. Just pointing out other options, but it does depend on what you're doing with it and all that I would go with a simple record (struct?) for the coordinates, if Coordinate doesn't already implement value comparisons
sibber
sibber2y ago
yeah id make coordinate a record struct
D.Mentia
D.Mentia2y ago
Also just btw, dictionaries and hashsets don't use the hash for a real equality check; looking up something with the same hash (but different Equals) won't give you a result. The hashes are just the fast way it can look things up, if there aren't many collisions in the hashes, but it still checks the Equals too
Birdman
BirdmanOP2y ago
thanks guys, i'll look into this further to see that's optimal, your support is appreciated 👍
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server