我在C#中有一个哈希集合,如果在遍历哈希集合时满足条件,就会从哈希集合中删除元素,但不能使用下面的foreach循环来实现。
foreach (String hashVal in hashset)
{
if (hashVal == "somestring")
{
hash.Remove("somestring");
}
}
那么,我如何在迭代时删除元素呢?
使用HashSet的RemoveWhere方法:
hashset.RemoveWhere(s => s == "somestring");
你需要将条件/谓词作为参数传递给该方法。与谓词匹配的哈希集中的任何项都将被移除。
这避免了在迭代哈希集时修改它的问题。
针对你的评论:
's' 表示当前正在从哈希集内部评估的项。
上述代码等同于:
hashset.RemoveWhere(delegate(string s) {return s == "somestring";});
或:hashset.RemoveWhere(ShouldRemove);
public bool ShouldRemove(string s)
{
return s == "somestring";
}
编辑:
我突然想到一个事情:由于HashSet是一个不包含重复值的集合,所以只需调用hashset.Remove("somestring")
就足够了。不需要使用循环来执行,因为永远不会有多个匹配项。
在使用枚举器遍历集合时,不可以从其中删除项目。解决此问题的两种方法是:
HashSet
的情况下可能不是一个选项)第二种方法的示例:
HashSet<string> hashSet = new HashSet<string>();
hashSet.Add("one");
hashSet.Add("two");
List<string> itemsToRemove = new List<string>();
foreach (var item in hashSet)
{
if (item == "one")
{
itemsToRemove.Add(item);
}
}
foreach (var item in itemsToRemove)
{
hashSet.Remove(item);
}
HashSet<string> anotherHashSet = new HashSet<string>();
foreach (var item in hashSet)
{
if (!shouldBeRemoved)
{
anotherSet.Add(item);
}
}
hashSet = anotherHashSet;
这里有一个更简单的解决方案。
var mySet = new HashSet<string>();
foreach(var val in mySet.ToArray() {
Console.WriteLine(val);
mySet.Remove(val);
}
.ToArray()已经为您创建了一个副本。您可以尽情循环。
对于那些正在寻找一种在移除HashSet中元素的同时处理它们的方法的人,我是这样做的
var set = new HashSet<int> {1, 2, 3};
while (set.Count > 0)
{
var element = set.FirstOrDefault();
Process(element);
set.Remove(element);
}
foreach
循环进行处理,然后在完成后清除集合? - c-chavez For (index = last to first)
If(ShouldRemove(index)) Then
Remove(index)
ConcurrentModificationException
的问题吧?我想知道C#是如何处理的。 - PatPeterRemoveWhere
时,在foreach
循环中会导致System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
。 - PatPeter