【问题标题】:Filtering out values from a C# Generic Dictionary从 C# 通用字典中过滤掉值
【发布时间】:2011-01-09 01:16:53
【问题描述】:

我有一个 C# 字典 Dictionary<Guid, MyObject>,需要根据 MyObject 的属性进行过滤。

例如,我想从字典中删除MyObject.BooleanProperty = false 所在的所有记录。实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: c# generics dictionary filtering


    【解决方案1】:

    如果您不关心创建包含所需项目的新字典并丢弃旧字典,只需尝试:

    dic = dic.Where(i => i.Value.BooleanProperty)
             .ToDictionary(i => i.Key, i => i.Value);
    

    如果您无法创建新字典并且由于某种原因需要更改旧字典(例如当它被外部引用并且您无法更新所有引用时:

    foreach (var item in dic.Where(item => !item.Value.BooleanProperty).ToList())
        dic.Remove(item.Key);
    

    请注意,ToList 在此处是必需的,因为您正在修改基础集合。如果您更改基础集合,则在其上工作以查询值的枚举器将无法使用,并将在下一次循环迭代中引发异常。 ToList 在更改字典之前缓存值。

    【讨论】:

    • 我想知道我需要在 ToDictionary 方法中传递哪些参数。谢谢! +1
    【解决方案2】:

    由于 Dictionary 实现了IEnumerable<KeyValuePair<Key, Value>>,所以你可以直接使用Where

    var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty);
    

    如果需要,要重新创建一个新字典,请使用ToDictionary 方法。

    【讨论】:

    • 确保您在顶部包含 System.Linq using 语句。
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:
          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);
          }
      

      【讨论】:

        【解决方案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);
            }
        

        用法

        例子:

            var onlyWithPositiveValues = allNumbers.Filter(it => it.Value > 0);
        

        【讨论】:

          【解决方案6】:

          我为我的项目添加了以下扩展方法,允许您过滤 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);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-11-25
            • 1970-01-01
            • 1970-01-01
            • 2021-07-05
            • 2021-12-11
            • 1970-01-01
            • 2020-10-12
            • 1970-01-01
            相关资源
            最近更新 更多