过滤掉C#通用词典中的值

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在更改字典之前缓存值.

  • 我想知道需要在 ToDictionary 方法中传递哪些参数。谢谢你!+1 (2认同)

Lee*_*Lee 61

自Dictionary实现以来IEnumerable<KeyValuePair<Key, Value>>,您可以使用Where:

var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty);
Run Code Online (Sandbox Code Playgroud)

要在需要时重新创建新字典,请使用该ToDictionary方法.

  • 确保顶部包含 System.Linq using 语句。 (3认同)

Ode*_*ded 7

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

var filtered = from kvp in myDictionary
               where !kvp.Value.BooleanProperty
               select kvp
Run Code Online (Sandbox Code Playgroud)


Rya*_*ams 7

    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)


And*_*ndi 5

这是一个通用解决方案,不仅适用于值的布尔属性。

方法

提醒:扩展方法必须放在静态类中。不要忘记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)