从ac#Dictionary中删除多个匹配谓词的项目的最佳方法?

我需要从字典中删除多个项目。 一个简单的方法如下:

List<string> keystoremove= new List<string>(); foreach (KeyValuePair<string,object> k in MyCollection) if (k.Value.Member==foo) keystoremove.Add(k.Key); foreach (string s in keystoremove) MyCollection.Remove(s); 

我不能直接删除foreach块中的项目的原因是,这将抛出一个exception(“集合被修改…”)

我想要做以下事情:

  MyCollection.RemoveAll(x =>x.Member==foo) 

但是Dictionary <>类不像List <> Class那样公开一个RemoveAll(Predicate <> Match)方法。

什么是最好的方式(既明智又明智)做到这一点?

6 Solutions collect form web for “从ac#Dictionary中删除多个匹配谓词的项目的最佳方法?”

这是另一种方式

 foreach ( var s in MyCollection.Where(kv => kv.Value.Member == foo).ToList() ) { MyCollection.Remove(s.Key); } 

直接将代码推入列表允许您避免“枚举时移除”问题。 .ToList()将在foreach真正开始之前强制枚举。

你可以创build扩展方法 :

 public static class DictionaryExtensions { public static void RemoveAll<TKey, TValue>(this Dictionary<TKey, TValue> dic, Func<TValue, bool> predicate) { var keys = dic.Keys.Where(k => predicate(dic[k])).ToList(); foreach (var key in keys) { dic.Remove(key); } } } ... dictionary.RemoveAll(x => x.Member == foo); 

而不是删除,只是做相反的事情。 从旧的只包含您感兴趣的元素创build一个新的字典。

 public Dictionary<T, U> NewDictionaryFiltered<T, U> ( Dictionary<T, U> source, Func<T, U, bool> filter ) { return source .Where(x => filter(x.Key, x.Value)) .ToDictionary(x => x.Key, x => x.Value); } 

Aku的扩展方法解决scheme的修改版本。 主要区别是它允许谓词使用字典键。 一个小的区别是它扩展了IDictionary而不是Dictionary。

 public static class DictionaryExtensions { public static void RemoveAll<TKey, TValue>(this IDictionary<TKey, TValue> dic, Func<TKey, TValue, bool> predicate) { var keys = dic.Keys.Where(k => predicate(k, dic[k])).ToList(); foreach (var key in keys) { dic.Remove(key); } } } . . . dictionary.RemoveAll((k,v) => v.Member == foo); 

你可以改变你的循环使用索引(即FOR而不是FOREACH)? 当然,你必须向后循环,也就是说,计数-1降到零。

而不是去除反过来(从旧的只包含你感兴趣的元素创build一个新的字典),让垃圾回收器照顾旧的字典:

 var newDictionary = oldDictionary.Where(x => x.Value != foo); 
  • Linq:GroupBy,Sum和Count
  • LINQ to SQL和有序结果的运行总数
  • string中出现的字符数
  • recursion层次 - 使用Linq的recursion查询
  • Linq中有多个WHERE子句
  • 使用LINQ对List <string>中的所有string进行Concat
  • LINQ - 查找一个列表中不在另一个列表中的所有项目
  • 优雅的方式来结合多个元素的集合?
  • 为LINQ的Distinct()使用相等比较器的委托
  • 为什么不支持C#静态类扩展方法?
  • 好的方法来获得在C#中的字典的最高价值的关键