Basically I want something like Dictionary
I have written such a dictionary and posted it on my blog. It will give you a nice API like this:
DoubleKeyDictionary<int, string, string> books = new DoubleKeyDictionary<string, string, string>();
bookListEx.Add(1, “21/12/2009″, “Lord of the Rings - Fellowship of the Ring”);
You can also do "Equals" on two dictionaries and for-each over it.
Please note that there are at least one bug in the code (as discovered in the comments) and no unit tests etc. When (yeah!) I get some time I'll update the code with unit tests...
Did you consider holding two dictionaries, one for each key? Adding an item would add it to both.
Removal means removing from both dictionaries too, and requires both keys. To remove with just one key, the item would have to store both keys. If it doesn't already hold both keys, you could wrap it in a container object that holds both keys and the item.
Check out this article on CodeProject: http://www.codeproject.com/KB/recipes/multikey-dictionary.aspx
This is clearly the right way to do a multi-key dictionary ;)
So you want a multi-index dictionary, supports lookups based on any key, and supports extensions to multiple keys?
Maybe you're thinking of the wrong data structure, try a KD-Tree instead. An immutable KD-tree would satisfy the thread-safety requirement.
KD-trees have some major advantages over the naive Dictionary{Key1, Dictionary{Key2, Value}}
approach, namely that you can search for all fields based on Key2 without knowing Key1. Additionally, KD-trees allow you to search for keys which are near some other key. For example, dating sites classify people into dozens of groups (smoker/non-smoker, gender, religion, lifestyle, age, height), then return nearest neighbors based on your query.
Here's a C# and Java implementation:
http://home.wlu.edu/~levys/software/kd/ (broken link, archived at https://web.archive.org/web/20190609084214/http://home.wlu.edu/~levys/software/kd/)
You could just use a regular dictionary for this and insert the value twice, once for each key. To delete you remove both keys.
Upsides:
Downsides:
size()
is doubled.Create simple class to store Tkey1, TKey2, TValue, make List of them and use LINQ to query such structure would be an option.