Get Index of a Dictionary from an array of Dictionaries for a given Key and Value

Viewed 71

I have a Dictionary<string, string>[] array, where each element is a Dictionary<string, string> with the same Keys and different Values.

How to get the index of the object for a given Key and Value?

For example, if the dictionary array has two elements as:

    [0]: {'Key1', 'ValueA}
         {'Key2', 'ValueB}
    [1]: {'Key1', 'ValueC}
         {'Key2', 'ValueD}

How to get the index where 'Key2' = 'ValueD'? So, Index result = 1.

3 Answers

You can use following LINQ query which is like a single loop that breaks as soon as possible:

int index = dictionaries
    .Select((dict, index) => (dict, index)) // put the dictionary and it's index in a ValueTuple
    .Where(x => x.dict.Any(kv => kv.Key == "Key2" && kv.Value == "ValueD")) // filter by key & value
    .Select(x => x.index) // select the index
    .DefaultIfEmpty(-1)   // if no dictionary met the condition you want -1 as result
    .First(); // this is safe, you get either a single index or -1 as fallback 

but note that you are losing the fast lookup capabilities of a dictionary with your approach.

Edit: Somebody's approach is more efficient, you can combine it with this:

int index = dictionaries
    .Select((dict, index) => (dict, index)) // put the dictionary and it's index in a ValueTuple
    .Where(x => x.dict.TryGetValue("Key2", out string value) && value == "ValueD") // filter by key & value
    .Select(x => x.index) // select the index
    .DefaultIfEmpty(-1) // if no dictionary met the condition you want -1 as result
    .First(); // this is safe, you get either a single index or -1 as fallback 

In this solution, searching each Dictionary for the given value is O(1) and not O(n) as in the other solutions:

string expectedKey = "Key2";
string expectedValue = "ValueD";
var item = array.FirstOrDefault(x => x.TryGetValue(expectedKey , out string value) && value == expectedValue);
if(item == null)
{
   Console.WriteLine("entry wasn't found in any dictionary");
   return;
}
int index = Array.IndexOf(array, item);
var item = array.Where(x=>x.Any(y=>y.Key == "Key2" && y.Value == "ValueD")).First();

var index = array.IndexOf(item);
Related