从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);