Get dictionary key by value
Values do not necessarily have to be unique, so you have to do a lookup. You can do something like this:
var myKey = types.FirstOrDefault(x => x.Value == "one").Key;
If values are unique and are inserted less frequently than read, then create an inverse dictionary where values are keys and keys are values.
You could do that:
- By looping through all the
KeyValuePair<TKey, TValue>
's in the dictionary (which will be a sizable performance hit if you have a number of entries in the dictionary) - Use two dictionaries, one for value-to-key mapping and one for key-to-value mapping (which would take up twice as much space in memory).
Use Method 1 if performance is not a consideration, and use Method 2 if memory is not a consideration.
Also, all keys must be unique, but the values are not required to be unique. You may have more than one key with the specified value.
I was in a situation where LINQ binding was not available and had to expand lambda explicitly. It resulted in a simple function:
public static T KeyByValue<T, W>(this Dictionary<T, W> dict, W val)
{
T key = default;
foreach (KeyValuePair<T, W> pair in dict)
{
if (EqualityComparer<W>.Default.Equals(pair.Value, val))
{
key = pair.Key;
break;
}
}
return key;
}
Call it like follows:
public static void Main()
{
Dictionary<string, string> dict = new Dictionary<string, string>()
{
{"1", "one"},
{"2", "two"},
{"3", "three"}
};
string key = KeyByValue(dict, "two");
Console.WriteLine("Key: " + key);
}
It works on .NET 2.0 and in other limited environments.
public static string GetKeyFromValue(string valueVar)
{
foreach (string keyVar in dictionaryVar.Keys)
{
if (dictionaryVar[keyVar] == valueVar)
{
return keyVar;
}
}
return null;
}
Other people may have more efficient answers, but I find this personally more intuitive and it works in my case.