我需要从Dictionary中删除多个项目.一种简单的方法如下:
Listkeystoremove= new List (); foreach (KeyValuePair k in MyCollection) if (k.Value.Member==foo) keystoremove.Add(k.Key); foreach (string s in keystoremove) MyCollection.Remove(s);
我无法直接删除foreach块中的项目的原因是这会抛出异常("Collection was modified ...")
我想做以下事情:
MyCollection.RemoveAll(x =>x.Member==foo)
但是Dictionary <>类没有公开RemoveAll(Predicate <> Match)方法,就像List <> Class那样.
这样做的最佳方式(性能明智和优雅明智)是什么?
这是另一种方式
foreach ( var s in MyCollection.Where(kv => kv.Value.Member == foo).ToList() ) { MyCollection.Remove(s.Key); }
直接将代码推送到列表中可以避免"在枚举时删除"问题.在.ToList()
将迫使枚举真正开始在foreach之前.
你可以创建一个扩展方法:
public static class DictionaryExtensions { public static void RemoveAll(this IDictionary dict, Func predicate) { var keys = dict.Keys.Where(k => predicate(dict[k])).ToList(); foreach (var key in keys) { dict.Remove(key); } } } ... dictionary.RemoveAll(x => x.Member == foo);
而不是删除,只是做反过来.从旧的字典创建一个只包含您感兴趣的元素的字典.
public DictionaryNewDictionaryFiltered ( Dictionary source, Func filter ) { return source .Where(x => filter(x.Key, x.Value)) .ToDictionary(x => x.Key, x => x.Value); }
修改版Aku的扩展方法解决方案.主要区别在于它允许谓词使用字典键.一个细微的差别是它扩展了IDictionary而不是Dictionary.
public static class DictionaryExtensions { public static void RemoveAll(this IDictionary dic, Func 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);