从 C# 通用字典中过滤掉值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2131648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Filtering out values from a C# Generic Dictionary
提问by Fiona - myaccessible.website
I have a C# dictionary, Dictionary<Guid, MyObject>
that I need to be filtered based on a property of MyObject
.
我有一个 C# 字典,Dictionary<Guid, MyObject>
我需要根据MyObject
.
For example, I want to remove all records from the dictionary where MyObject.BooleanProperty = false
. What is the best way of acheiving this?
例如,我想从字典中删除所有记录 where MyObject.BooleanProperty = false
。实现这一目标的最佳方法是什么?
采纳答案by Lee
Since Dictionary implements IEnumerable<KeyValuePair<Key, Value>>
, you can just use Where
:
由于 Dictionary 实现IEnumerable<KeyValuePair<Key, Value>>
,您可以只使用Where
:
var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty);
To recreate a new dictionary if you need it, use the ToDictionary
method.
如果需要,要重新创建新字典,请使用ToDictionary
方法。
回答by Mehrdad Afshari
If you don't care about creating a new dictionary with the desired items and throwing away the old one, simply try:
如果您不关心使用所需项目创建新字典并丢弃旧字典,只需尝试:
dic = dic.Where(i => i.Value.BooleanProperty)
.ToDictionary(i => i.Key, i => i.Value);
If you can't create a new dictionary and need to alter the old one for some reason (like when it's externally referenced and you can't update all the references:
如果您无法创建新字典并且出于某种原因需要更改旧字典(例如当它被外部引用并且您无法更新所有引用时:
foreach (var item in dic.Where(item => !item.Value.BooleanProperty).ToList())
dic.Remove(item.Key);
Note that ToList
is necessary here since you're modifying the underlying collection. If you change the underlying collection, the enumerator working on it to query the values will be unusable and will throw an exception in the next loop iteration. ToList
caches the values before altering the dictionary at all.
请注意,这ToList
是必要的,因为您正在修改基础集合。如果您更改基础集合,则使用它来查询值的枚举器将无法使用,并将在下一次循环迭代中引发异常。ToList
在完全改变字典之前缓存值。
回答by Oded
回答by aaaaaa
I added the following extension method for my project which allows you to filter an IDictionary.
我为我的项目添加了以下扩展方法,它允许您过滤 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;
}
);
}
Usage:
用法:
IDictionary<int, Person> oldPeople = personIdToPerson.KeepWhen(p => p.age > 29);
回答by Ryan Williams
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);
}
回答by Andi
Here is a general solution, working not only for boolean properties of the values.
这是一个通用解决方案,不仅适用于值的布尔属性。
Method
方法
Reminder: Extension methods must be placed in static classes. Dont forget the using System.Linq;
statement at the top of the source file.
提醒:扩展方法必须放在静态类中。不要忘记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);
}
Usage
用法
Example:
例子:
var onlyWithPositiveValues = allNumbers.Filter(it => it.Value > 0);