Search For keys Matching values in a dictionary of list in C#

I have a dictionary of lists.

var dicAclWithCommonDsEffectivity = new Dictionary<string, List<int>>();
var list1 = new List<int>(){1,2,3};
var list2 = new List<int>(){2,4,6};
var list3 = new List<int>(){3,7,6};
var list4 = new List<int>(){8,7,6};

dicAclWithCommonDsEffectivity.Add("ab",list1);
dicAclWithCommonDsEffectivity.Add("bc",list2);
dicAclWithCommonDsEffectivity.Add("cd",list3);
dicAclWithCommonDsEffectivity.Add("de",list4);

I want to get the keys in dictionary for which atleast one matching value with the current key list. for key "ab"(first list). I should get: "ab","bc" and "cd".Since these lists contain one of the matching element in {1,2,3}

Is there a way without looping through each item in the list of dictionary value.

Jon Skeet
people
quotationmark

Is there a way without looping through each item in the list of dictionary value.

Something has to loop - dictionaries are only designed to look up by key, and you're not doing that other than for the first check.

You can do this fairly easily though:

private IEnumerable<string> GetMatchingKeys(
    Dictionary<string, List<int>> dictionary, string key)
{
    // TODO: Use TryGetValue if key might not be in dictionary
    HashSet<int> elements = new HashSet<int>(dictionary[key]);
    return dictionary.Where(pair => pair.Value.Any(x => elements.Contains(x)))
                     .Select(pair => pair.Key);
}

This uses the fact that Dictionary implements IEnumerable<KeyValuePair<TKey, TValue>> - so the Where clause checks a particular entry by spotting if any of the elements of its value matches any of the elements of the original value. The Select clause then projects the pair to just the key.

If you need to do this a lot and you're concerned about efficiency, another alternative would be to build a second dictionary from int to List<string> - basically a reverse mapping. You'd need to maintain that, but then you could easily fetch all the "original keys" mapping to each of the values corresponding to the given key, and just use Distinct to avoid duplicates.

people

See more on this question at Stackoverflow