Tuples( or arrays ) as Dictionary keys in C?

If you are on . NET 4.0 use a Tuple: lookup = new Dictionary, string>() If not you can define a Tuple and use that as the key. The Tuple needs to override GetHashCode, Equals and IEquatable: struct Tuple : IEquatable> { readonly T first; readonly U second; readonly W third; public Tuple(T first, U second, W third) { this.

First = first; this. Second = second; this. Third = third; } public T First { get { return first; } } public U Second { get { return second; } } public W Third { get { return third; } } public override int GetHashCode() { return first.GetHashCode() ^ second.GetHashCode() ^ third.GetHashCode(); } public override bool Equals(object obj) { if (obj == null || GetType()!

= obj.GetType()) { return false; } return Equals((Tuple)obj); } public bool Equals(Tuple other) { return other.first. Equals(first) && other.second. Equals(second) && other.third.

Equals(third); } }.

If you are on . NET 4.0 use a Tuple: lookup = new Dictionary, string>(); If not you can define a Tuple and use that as the key. The Tuple needs to override GetHashCode, Equals and IEquatable: struct Tuple : IEquatable> { readonly T first; readonly U second; readonly W third; public Tuple(T first, U second, W third) { this.

First = first; this. Second = second; this. Third = third; } public T First { get { return first; } } public U Second { get { return second; } } public W Third { get { return third; } } public override int GetHashCode() { return first.GetHashCode() ^ second.GetHashCode() ^ third.GetHashCode(); } public override bool Equals(object obj) { if (obj == null || GetType()!

= obj.GetType()) { return false; } return Equals((Tuple)obj); } public bool Equals(Tuple other) { return other.first. Equals(first) && other.second. Equals(second) && other.third.

Equals(third); } }.

Download a copy of VS2010 Beta, and you can personally confirm that such a type in actual fact is in the . NET 4.0 libraries ;) – jerryjvl Jun 5 '09 at 14:12 2 This struct should also implement IEquatable>. That way you can avoid boxing when Equals() is called in the case of hash code collisions.

– Dustin Campbell Jun 5 '09 at 14:20 Thanks Dustin. Added it to the example. – Hallgrim Jun 8 '09 at 9:13 1 You almost got it right, no ToString implementation.

Though that's mostly icing on the cake you implemented the important stuff. +1 – RCIX Nov 4 '09 at 8:50 2 Your GetHashCode implementation isn't very good. It's invariant under permutation of the fields.

– CodeInChaos Aug 30 at 18:37.

If for some reason you really want to avoid creating your own Tuple class, or using on built into . NET 4.0, there is one other approach possible; you can combine the three key values together into a single value. For example, if the three values are integer types together not taking more than 64 bits, you could combine them into a ulong.

Worst-case you can always use a string, as long as you make sure the three components in it are delimited with some character or sequence that does not occur inside the components of the key, for example, with three numbers you could try: string. Format("{0}#{1}#{2}", key1, key2, key3) There is obviously some composition overhead in this approach, but depending on what you are using it for this may be trivial enough not to care about it.

4 While this would work, it has a bad code smell. – John Gietzen Jun 5 '09 at 17:31 I'd say that it depends strongly on context though; if I had three integer types to combine, and performance was not critical, this works perfectly fine with minimal chance of making a mistake. Of course, all of this is completely redundant as of .

NET 4, since Microsoft will be providing us with (presumably correct! ) Tuple types out of the box. – jerryjvl Jun 6 '09 at 1:33 Nice idea for large domains.

– ymihere Jul 17 '09 at 15:15.

I would overload your Tuple with a proper GetHashCode, and just use it as the key. As long as you overload the proper methods, you should see decent performance.

1 IComparable doesn't have an effect on how keys are stored or located in a Dictionary. It's all done through GetHashCode() and an IEqualityComparer. Implementing IEquatable will achieve better performance because it alleviates the boxing caused by the default EqualityComparer, which falls back on the Equals(object) function.

– Dustin Campbell Jun 5 '09 at 14:24 I was going to mention GetHashCode, but I thought that the Dictionary used IComparable in the case that the HashCodes were Identical... guess I was wrong. – John Gietzen Jun 5 '09 at 17:30.

Return ((IStructuralEquatable) this). M_Item1) && comparer. M_Item2) && comparer.

Return ((IStructuralComparable) this). Throw new ArgumentException(Environment. C = comparer.

C = comparer. Return ((IStructuralEquatable) this). Return ((IStructuralEquatable) this).

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions