从 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:43:49  来源:igfitidea点击:

Filtering out values from a C# Generic Dictionary

c#genericsdictionaryfiltering

提问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 ToDictionarymethod.

如果需要,要重新创建新字典,请使用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 ToListis 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. ToListcaches the values before altering the dictionary at all.

请注意,这ToList是必要的,因为您正在修改基础集合。如果您更改基础集合,则使用它来查询值的枚举器将无法使用,并将在下一次循环迭代中引发异常。ToList在完全改变字典之前缓存值。

回答by Oded

You can simply use the Linqwhere clause:

您可以简单地使用Linqwhere 子句:

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

回答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);