agenthost agenthost - 1 month ago 4x
C# Question

How to find the key of a dictionary when the value is a list of objects in C#?

I want to find the corresponding key when I have a list of objects as a value.
Suppose I have a Dictionary,

Dictionary<string, List<object>> dict = new Dictionary<string, List<object>>();

I know I could do something like,

foreach (var item in dict)
foreach (var subItem in item.Value)
if (subItem.Equals(foo))

But this takes a lot of time I have a huge data set. Is there a faster solution to this?

I know that the normal way of finding keys given the value, using LINQ is something like:

var keysWithMatchingValues = dict.Where(p => p.Value == myObject).Select(p => p.Key);

I am looking for a similar solution in my situation.


LINQ isn't more performant most times, but it's often easier to write correct and readable code with LINQ. If no duplicate values are possible i'd use a HashSet<T> instead of the list. If you know what type it is i'd use that type instead of object.

The LINQ version of your code would be....

  1. with List.Contains:

    List<string> keysWithValue =  dict
        .Where(kv => kv.Value.Contains(foo))
        .Select(kv => kv.Key);
  2. or Enumerable.Any:

    List<string> keysWithValue =  dict
        .Where(kv => kv.Value.Any(v => foo.Equals(v)))
        .Select(kv => kv.Key);

But as mentioned this wouldn't be more efficient. One way to improve performance would be to use a Lookup<TKey, TValue>. If the dictionary doesn't change you only need to create it once:

var valueToKeyLookup = dict  // make it an instance field, so that you don't have to create it always
    .SelectMany(kv => kv.Value
        .Select(v => new {Key = kv.Key, Value = v})
    .ToLookup(x => x.Value, x => x.Key);

Now the remaining code is very concise and efficient:

List<string> allKeysWithFoo = valueToKeyLookup[foo].ToList();

Note that this will even work if no list contains that value, then the result will be an empty list.