Fio*_*ite 62 c# generics dictionary filtering
我有一个C#字典,Dictionary<Guid, MyObject>
我需要根据属性进行过滤MyObject
.
例如,我想删除字典中的所有记录MyObject.BooleanProperty = false
.实现这一目标的最佳方式是什么?
Meh*_*ari 92
如果您不关心使用所需项目创建新词典并丢弃旧词典,只需尝试:
dic = dic.Where(i => i.Value.BooleanProperty)
.ToDictionary(i => i.Key, i => i.Value);
Run Code Online (Sandbox Code Playgroud)
如果您无法创建新字典并且由于某种原因需要更改旧字典(例如,当它被外部引用并且您无法更新所有引用时:
foreach (var item in dic.Where(item => !item.Value.BooleanProperty).ToList())
dic.Remove(item.Key);
Run Code Online (Sandbox Code Playgroud)
请注意,这ToList
是必要的,因为您正在修改基础集合.如果更改基础集合,则用于查询值的枚举器将无法使用,并将在下一个循环迭代中引发异常.ToList
在更改字典之前缓存值.
Lee*_*Lee 61
自Dictionary实现以来IEnumerable<KeyValuePair<Key, Value>>
,您可以使用Where
:
var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty);
Run Code Online (Sandbox Code Playgroud)
要在需要时重新创建新字典,请使用该ToDictionary
方法.
您可以简单地使用Linq where子句:
var filtered = from kvp in myDictionary
where !kvp.Value.BooleanProperty
select kvp
Run Code Online (Sandbox Code Playgroud)
public static Dictionary<TKey, TValue> Where<TKey, TValue>(this Dictionary<TKey, TValue> instance, Func<KeyValuePair<TKey, TValue>, bool> predicate)
{
return Enumerable.Where(instance, predicate)
.ToDictionary(item => item.Key, item => item.Value);
}
Run Code Online (Sandbox Code Playgroud)
这是一个通用解决方案,不仅适用于值的布尔属性。
方法
提醒:扩展方法必须放在静态类中。不要忘记using System.Linq;
源文件顶部的语句。
/// <summary>
/// Creates a filtered copy of this dictionary, using the given predicate.
/// </summary>
public static Dictionary<K, V> Filter<K, V>(this Dictionary<K, V> dict,
Predicate<KeyValuePair<K, V>> pred) {
return dict.Where(it => pred(it)).ToDictionary(it => it.Key, it => it.Value);
}
Run Code Online (Sandbox Code Playgroud)
用法
例子:
var onlyWithPositiveValues = allNumbers.Filter(it => it.Value > 0);
Run Code Online (Sandbox Code Playgroud)