I am looking for a generic, bidirectional 1 to 1 Dictionary class in C# (2), ie. a BiDictionaryOneToOne<T, S>
which is guaranteed to only contain one of each value and key (up to RefEquals anyway), and which can be searched using either key or value. Anyone know of one, or should I just implement it myself? I can't believe that I'm the first person to need this...
There is a BiDictionary in the answers to this question, but it is not for unique elements (and also does not implement RemoveByFirst(T t) or RemoveBySecond(S s)).
Thanks!
A more complete implementation of bidirectional dictionary:
Dictionary<TKey,TValue>
(except infrastructure interfaces):IDictionary<TKey, TValue>
IReadOnlyDictionary<TKey, TValue>
IDictionary
ICollection<KeyValuePair<TKey, TValue>>
(this one and below are the base interfaces of the ones above)ICollection
IReadOnlyCollection<KeyValuePair<TKey, TValue>>
IEnumerable<KeyValuePair<TKey, TValue>>
IEnumerable
SerializableAttribute
.DebuggerDisplayAttribute
(with Count info) andDebuggerTypeProxyAttribute
(for displaying key-value pairs in watches).IDictionary<TValue, TKey> Reverse
property and also implements all interfaces mentioned above. All operations on either dictionaries modify both.Usage:
Code is available in my private framework on GitHub: BiDictionary(TFirst,TSecond).cs (permalink, search).
Copy:
This is same as accepted answer, but I provided
Update
methods as well, and over all little more fleshed out:Similar to my answer here
Few things to note:
I have implemented only
IEnumerable<>
. I don't thinkICollection<>
makes sense here since the method names all could be way different for this special collection structure. Up to you to decide what should go insideIEnumerable<>
. So now you have collection initializer syntax too, likeI have attempted for some weird exceptions to be thrown here and there - just for data integrity. Just to be on the safer side so that you know if ever my code has bugs.
Performance: You can lookup for
Value
with either of theKeys
, which meansGet
andContains
method require just 1 lookup (O(1)).Add
requires 2 lookups and 2 adds.Update
requires 1 lookup and 2 adds.Remove
takes 3 lookups. All similar to accepted answer.A bit late, but here's an implementation I wrote a while back. It handles a few interesting edge cases, such as when the key overrides the equality check to perform partial equality. This results in the main dictionary storing
A => 1
but the inverse storing1 => A'
.You access the inverse dictionary via the
Inverse
property.Original source and tests on github.
The question you refer to also shows a one-to-one implementation in this answer. Adding RemoveByFirst and RemoveBySecond would be trivial - as would implementing extra interfaces etc.
Another extension to the accepted answer. It implements IEnumerable so one can use foreach with that. I realize there are more answers with IEnumerable implementation but this one uses structs so it is garbage collector friendly. This is especially usefull in Unity engine (checked with the profiler).
I have created such a class, using C5 collection classes.