2015-03-15 2 views
0

У меня есть List<Dictionary<string,string>>, называемый recsList. Следующие два запроса проверяют для любого экземпляра определенных значений в двух отдельных ключах в каждом словаре в recsList.LINQ to Dictionary with AND condition

Мне нужно объединить эти запросы с условием И, чтобы получить истинное значение, если тот же Словарь имеет оба условия.

bool multipleCodesFound = recsList.SelectMany(a => a) 
    .Where(x => x.Key.Equals("multCodesFound")).Any((y => y.Value == (true).ToString())); 
bool doubleCRLFFound = recsList.SelectMany(a => a) 
    .Where(x => x.Key.Equals("CountofCRLF")).Any(y => int.Parse(y.Value) > 1); 
+0

ИМО, использовать третий bool и выполните «и» между двумя первыми результатами, вместо того, чтобы сделать уродливый огромный запрос LINQ. –

+0

Проблема в том, что это даст мне ответ, что recsList содержит словарь с одним (или обоими) условий и другим Словарем с другим условием (или обоими). Я должен быть уверен, что у того же Словаря есть и то, и другое. –

+0

Почему вы используете '.Any()' и не добавляете это предложение в 'Where'? –

ответ

3

Похоже, это то, что вы хотите. Это также должно быть более эффективным, чем то, что вы делаете выше, потому что ваш подход перебирает лады каждого словаря до тех пор, пока не найдет совпадения (сводит на нет преимущества эффективности использования словарей):

bool isAMatch = recsList.Any(d => d.ContainsKey("multCodesFound")   && 
            d.ContainsKey("CountofCRLF")    && 
            d["multCodesFound"] == bool.TrueString && 
            int.Parse(d["CountofCRLF"]) > 1); 

Как ytoledano correcly указывает, использование ContainsKey, за которым следует поиск словаря, неэффективно, потому что для этого требуются два поиска. Чтобы избежать этой потери производительности, вы можете использовать подход ниже, хотя я бы сказал, что в подобных случаях может быть стоит принимать удар по производительности, с тем чтобы иметь более сжатый код, указанный выше:

bool isAMatch = recsList.Any(d => { 
    string val; 
    return d.TryGetValue("multCodesFound", out val) && 
      val == bool.TrueString     && 
      d.TryGetValue("CountofCRLF", out val) && 
      int.Parse(val) > 1; 
}); 
+0

Я уже думал об этом. –

+2

Не лучше ли попробовать TryGetValue, чтобы избежать дублирования поиска в словаре? – ytoledano

+0

@ytoledano Я не знаю, является ли разница достаточно большой, чтобы беспокоиться большую часть времени, и, избегая штрафа за производительность, требуется уродливый код, но вы правы. Я добавил альтернативный подход с помощью 'TryGetValue()'. – JLRishe