从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)方法。

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

这是另一种方式

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