2016-10-07 2 views
2

У меня есть словарь, который содержит информацию из анализируемого тестового прогона. Ключ - это имя метода, а значение - это список TestRunProperties. Мой словарь содержит все методы из тестового прогона, и я хотел бы удалить методы, которые не выполнялись во время тестового прогона. Возможно ли это с Linq?Удаление определенных значений из словаря C# с Linq

TestRunProperties класс:

public class TestRunProperties 
{ 
    public string computerName { get; set; } 
    public TimeSpan duration { get; set; } 
    public string startTime { get; set; } 
    public string endTime { get; set; } 
    public string testName { get; set; } 
    public string outcome { get; set; } 
} 

Словарь:

//Key is the name of the method, value is the properties associated with each run 
private static Dictionary<string, List<TestRunProperties>> runResults = new Dictionary<string, List<TestRunProperties>>(); 

Я пробовал это, но я думаю, что я путаюсь с Where части:

runResults.Remove(runResults.Where(methodName => methodName.Value.Where(method => method.outcome.ToLower().Equals("failed")))); 

Я m совершенно новый для Linq и Lambda, и я все еще пытаюсь понять, как получить доступ к таким данным.

+0

Спасибо всем за вашу помощь, все действительно большие ответы! – Novastorm

ответ

3

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

public static class DictionaryExt 
{ 
    public static void RemoveAll<K, V>(this IDictionary<K, V> dict, Func<K, V, bool> predicate) 
    { 
     foreach (var key in dict.Keys.ToArray().Where(key => predicate(key, dict[key]))) 
      dict.Remove(key); 
    } 
} 

Это обычно будет более эффективным, чем создание совершенно нового словаря, особенно если количество элементов удаляется относительно низка по сравнению с размером из Словарь.

Ваш вызывающий код будет выглядеть следующим образом:

runResults.RemoveAll((key, methodName) => methodName.Value.Where(method => method.outcome.ToLower().Equals("failed"))); 

(я выбрал имя RemoveAll(), чтобы соответствовать List.RemoveAll().)

0

Чтобы быть честным, вы, вероятно, лучше выбрать новый словарь из существующего:

runResults.Select().ToDictionary(x => x.Key, x => x.Value.Where(x => x.Value.outcome != "failed")); 

* Editted, чтобы отразить список в словаре.

На самом деле, вы можете избавиться от них без каких-либо успешных результатов, делая это слишком:

runResults.Select(x => new { x.Key, x.Value.Where(x => x.Value.outcome != "failed")}).Where(x => x.Value.Any()).ToDictionary(x => x.Key, x => x.Value); 
+0

Я думаю, что есть недостающая часть выше; Значение - это список, а не отдельный TestRunProperty, поэтому я не могу получить доступ к нему. – Novastorm

+0

А так вам просто нужно запросить еще один уровень – gmn

1

Вы можете создать новый словарь по отфильтровывая недопустимых:

var filtered = runResults.ToDictionary(p => p.Key, p => p.Value.Where(m => m.outcome.ToLower() != "failed").ToList()); 

Ok , grrrrrr был быстрее :-)

+0

Спасибо, что это сработало! Ответ grrrrrr был близок, но пропустил точку или два :) – Novastorm

Смежные вопросы