views:

40

answers:

2

Is there any .NET type that would represent a set of key-value pairs where each key will only be paired with a single value (like a regular Dictionary), but also each value will only be paired with a single key? I've been thinking of this as an "invertible" dictionary because you could swap the keys with the values without any collisions. It shouldn't be hard to write such a class, and add methods like "TryGetKey" for a given value. However, I wanted to check if such a thing already existed somewhere, perhaps under a different name that I haven't thought of.

Also, considering the elegant answer to this question, would it be worthwhile for me to create a class to represent this invertible dictionary, when I could just as easily use LINQ to convert any dictionary to its value-key equivalent?

+3  A: 

I don't believe there is a class in the framework that does this, directly.

Also, considering the elegant answer to this question, would it be worthwhile for me to create a class to represent this invertible dictionary, when I could just as easily use LINQ to convert any dictionary to its value-key equivalent?

The answer to both of your questions really depends on how you are going to be accessing your data. If you need fast, constant time access based on key and value, you are most likely going to want to make your own collection.

This could be done very, very easily, though. Just wrap two Dictionary instances inside your class, and when you add in a new element, add to both - one with key/value and one with value/key. Your lookup routines can just pull from the appropriate collection, and it will remain near O(1) for access time.

If, however, memory is more of a concern, you could just use a single collection, and use LINQ to parse it. This is going to make your "reverse" lookup quite a bit slower, as you'll need to re-parse each time.

Reed Copsey
Well, for reference types, the memory overhead in having an extra dictionary wont be much, no?
cwap
@cwap: Dictionary overhead (at least on a 64 bit machine) is 24 bytes per entry if both key and value are reference types.
Jim Mischel
Encountered an error I'd not seen before in trying to write a class that implements both `IDictionary<TKey, TValue>` and `IDictionary<TValue, TKey>`: "'InvertibleDictionary<TKey,TValue>' cannot implement both 'System.Collections.Generic.IDictionary<TKey,TValue>' and 'System.Collections.Generic.IDictionary<TValue,TKey>' because they may unify for some type parameter substitutions". Guess I'll just implement one!
Sarah Vessels
@Sarah: I'd, personally, not implement either, and just expose the functionality meaningful for your situation. It's really more like an advanced lookup collection class, not necessarily a dictionary. If, however, your "normal" use will be to always pass through to one of the two dictionaries, and the reverse lookups are more rare, then you may want to just implement that one...
Reed Copsey
A: 

If you really needed such a data structure, you probably wouldn't want the overhead of converting it every time you did a lookup. That is, if you had a normal Dictionary<string,int>, every time you did a lookup by value, you'd have to go through that conversion. You could optimize it so you only did the conversion if the dictionary had changed (i.e. an item was added, removed, or changed), but it'd still be a pretty high price to pay.

Jim Mischel