从C#generics字典中过滤出值

我有一个C#字典, Dictionary<Guid, MyObject> ,我需要根据MyObject的属性进行过滤。

例如,我想从MyObject.BooleanProperty = false的字典中删除所有logging。 达到这个目标的最好方法是什么?

由于Dictionary实现了IEnumerable<KeyValuePair<Key, Value>> ,所以你可以使用where:

 var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty); 

要重新创build一个新的字典,如果需要的话,使用ToDictionary方法。

如果你不关心创build一个新的字典与所需的项目,扔掉旧的,只要尝试:

 dic = dic.Where(i => i.Value.BooleanProperty) .ToDictionary(i => i.Key, i => i.Value); 

如果你不能创build一个新的字典,并由于某种原因需要修改旧的字典(比如外部引用的时候,你不能更新所有的引用:

 foreach (var item in dic.Where(item => !item.Value.BooleanProperty).ToList()) dic.Remove(item.Key); 

请注意, ToList是必要的,因为您正在修改基础集合。 如果更改了底层集合,那么查询这些值的枚举器将不可用,并且会在下一个循环迭代中引发exception。 ToList在更改字典之前caching值。

您可以简单地使用Linq where子句:

 var filtered = from kvp in myDictionary where !kvp.Value.BooleanProperty select kvp 

我为我的项目添加了以下扩展方法,允许您筛选IDictionary。

 public static IDictionary<keyType, valType> KeepWhen<keyType, valType>( this IDictionary<keyType, valType> dict, Predicate<valType> predicate ) { return dict.Aggregate( new Dictionary<keyType, valType>(), (result, keyValPair) => { var key = keyValPair.Key; var val = keyValPair.Value; if (predicate(val)) result.Add(key, val); return result; } ); } 

用法:

 IDictionary<int, Person> oldPeople = personIdToPerson.KeepWhen(p => p.age > 29);