views:

421

answers:

4

Hi, I am using a StringDictionary to store key value pairs. I need to use the keys and values interchangeably i.e. I should be able to get the key from the value as in my case the values will be distinct.

Is there a direct way I could do it (without looping)? Or if there is any other collection I could use to achieve this?

Currently I am looping:

public String GetKeyFromValue(string value)
        {
            foreach (KeyValuePair<string, string> kvp in instance)
            { 
                if (String.Equals(kvp.Value, value))
                    return kvp.Key;
            }

            throw new Exception ("Key not found in FilterControlMapping");
        }

Any help is much appreciated. Thanks.

+1  A: 

The only way I can think of is two dictionaries.

D1 < Key, Value > D2 < Value, Key >

You would be repeating your data though. But you could search both keys and values this way.

nunespascal
A: 

This would also be possible using Dictionary:

Dictionary<string, string> sd = new Dictionary<string, string>();
string sKey = sd.Single(kvp => kvp.Value.Equals("A value")).Key;

Note that the Single method will throw if the value occurs more than once. You could use First or even FirstOrDefault.

Edit: As Jon Skeet commented this is still looping. The links he posted to a linked dictionary provide the solution.

Onots
That's *effectively* looping though, i.e. the complexity is O(n) instead of the desirable O(1).
Jon Skeet
Can I use => operator in 2.0?
Rashmi Pandit
No, you can't use the lambda expression. See http://stackoverflow.com/questions/556425/predicate-delegates-in-c on how to achieve the same in 2.0Though do note Jon Skeet's comment. This will still loop!
Onots
+3  A: 

You basically need to use two dictionaries encapsulated into one.

There are already implementations here and here in other Stack Overflow questions.

Jon Skeet
That would mean double the memory, wouldn't it?
Rashmi Pandit
The memory of what, exactly? You'd still only have the actual *objects* once (assuming we're talking about reference types), because each collection would just have references to the real values. Yes, the space required for the book-keeping etc would be doubled, but that's the price you pay for being able to look up both ways.
Jon Skeet
A: 

The best idea is to use Dictionary instead of StringDictionary as its obselete.. you can find out more about this here: http://stackoverflow.com/questions/627716/stringdictionary-vs-dictionarystring-string/627733#627733 regarding retrival you should go with linq internally it is using loops but still its much cleaner way..

Usman Masood
Hey thanks for the info. I had actually migrated from Dictionary<string, string> to StringDictionary. Time to revert back :)
Rashmi Pandit
you are welcome :)
Usman Masood