Dictionary where the key is a pair of integers
Maybe you should consider using a Tuple
var myDictionary = new Dictionary<Tuple<int,int>, List<string>>();
myDictionary.Add(new Tuple<int,int>(3, 3), "FirstItem");
myDictionary.Add(new Tuple<int,int>(5, 5), "SecondItem");
According to MSDN documentation, a Tuple
objects Equals
method will use the values of the two Tuple
objects. This would result in one entry per Tuple
in the outer dictionary and allow you to store a listing of the values per key.
Simply use a long
as key and combine the two int
keys
public class IntIntDict<T> : Dictionary<long, T>
{
public void Add(int key1, int key2, T value)
{
Add((((long)key1) << 32) + key2, value);
}
//TODO: Overload other methods
}
UPDATE
C# 7 introduces the new ValueTuple Struct together with a simplified tuple syntax. These tuples come in handy for compound keys. You can declare your dictionary and add entries like this:
var myDictionary = new Dictionary<(int, int), string>();
myDictionary.Add((3, 3), "FirstItem");
myDictionary.Add((5, 5), "SecondItem");
and look up values like this
string result = myDictionary[(5, 5)];
or
if (myDictionary.TryGetValue((5, 7), out string result)) {
//TODO: use result
}
For performance Dictionary requires a key that generates unique GetHashValue.
KeyValuePair is a value type and not recommended for a key.
ValueType.GetHashCode
If you call the derived type's GetHashCode method, the return value is not likely to be suitable for use as a key in a hash table. Additionally, if the value of one or more of those fields changes, the return value might become unsuitable for use as a key in a hash table. In either case, consider writing your own implementation of the GetHashCode method that more closely represents the concept of a hash code for the type.
Point is also a value value type and also not recommended for a key.
Tuple also generates a lot of duplicate GetHashCode and is not a good key.
The optimal key is one that generates unique keys.
Consider UInt16 i and UInt j as the two keys.
How can they be combined and generate unique hash?
Easy combine them into and UInt32.
UInt32 natively generates a perfect hash.
The alogorithm for packing two UInt16 into UInt32 is
(i * (UInt16.MaxValue + 1)) + j;
but it is even faster with
(UInt32)i << 16 | j;
myDictionary = new Dictionary<UInt32, string>();
With a perfect hash the Dictionary is O(1).
With a poor hash the Dictionary becomes O(n).