4

It seems like a pretty straightforward thing to add, but I just want to be sure .NET doesn't already provide one and save me from adding unnecessary code:

I need a lookup table (like a Dictionary) that instead using a key/value pair, uses the first key to find the second key, and vice versa. For example -

theList.Add("foo", "bar");
x = theList["foo"]; // Returns "bar"
y = theList["bar"]; // Returns "foo"

Thanks in advance!

svick
  • 9,999
  • 1
  • 37
  • 51
Jarryd Le Breton
  • 43
  • 1
  • 1
  • 4
  • 1
    What would this collection do when someone performs: `theList.Add("foo", "bar");` followed by `theList.Add("bar", "baz");` ? – rwong Aug 02 '15 at 07:39
  • 1
    This is a *bidirectional map*, usually called `BidiMap` or `BiMap` (or, since .NET calls maps dictionaries, in .NET, it would probably be called `BidiDictionary`, `BiDictionary`, or, if you want to be extra clever `Bictionary`). AFAIK, there is no such thing in the BCL, but you might find it in one of the other collections packages, e.g. [C5](https://www.itu.dk/research/c5/) or [PowerCollections](http://powercollections.codeplex.com). There are also about 20 questions about this in StackOverflow. – Jörg W Mittag Aug 02 '15 at 09:41
  • rwong - I would expect it to throw an exception in that case. Check my answer below -- this is what I was looking to achieve, I just wanted to know if it already had an implementation. Jörg - Thank you for this! I didn't know the name so I had no idea what to search for. Good to know. – Jarryd Le Breton Aug 02 '15 at 09:45

2 Answers2

9

There is no such datatype, probably because this is a very special requirement which can be easily solved by utilizing a dictionary and adding simply both pairs

 theDictionary.Add("foo", "bar");
 theDictionary.Add("bar", "foo");

Obviously, you can put this into a generic function like

void MyDictAdd(Dictionary<T,T> dict, T key1, T key2)
{
    dict.Add(key1,key2);
    dict.Add(key2,key1);
}
Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • Also, lookups are done with `dict[key]` which you forgot to mention! :) So if you have a dictionary as such: `var dict = new Dictionary { { "somekey", "somevalue" } };` then `dict["somekey"]` will return `"somevalue"`. – mausworks Aug 02 '15 at 11:24
  • Genius solution. But to implement Count and other functionality, logic is needed – Ozkan Oct 11 '18 at 11:58
  • This solution has one main drawback: key and value have to be the same type. – Zoman Dec 31 '18 at 19:36
  • @Zoman: that is not a "drawback of this solution", it is what the question necessarily implies. Or, if one needs mixed types, one can still use `object` as common type. – Doc Brown Jan 01 '19 at 01:28
0

Another possibility would be to create a method which would search both keys and values. Also this would and more complexity to the mix O(n) for the search. But would reduce memory usage.

string GetValue(string search, Dictionary<string, string> dictionary) {
    foreach(var pair in dictionary)
    {
        if (pair.Key == search) {
            return pair.Value;
        }
        else if (pair.Value == search) {
            return pair.Key;
        }
    }
    return null;
}
fsacer
  • 111
  • 4