30

我在 C# 中有一个哈希集,如果在迭代哈希集时满足条件,我将删除该哈希集,并且无法使用如下的 foreach 循环执行此操作。

foreach (String hashVal in hashset) 
{
     if (hashVal == "somestring") 
     {
            hash.Remove("somestring");
     }
}

那么,如何在迭代时删除元素?

4

5 回答 5

57

改用 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")就足够了。没有必要在循环中进行,因为永远不会超过一个匹配。

于 2009-09-26T21:43:34.023 回答
10

您不能在使用枚举器循环遍历集合时从集合中删除项目。解决这个问题的两种方法是:

  • 使用常规索引 for 循环在集合上向后循环(我认为在 a 的情况下这不是一个选项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);
}
于 2009-09-26T21:44:07.873 回答
8

我会避免使用两个 foreach 循环 - 一个 foreach 循环就足够了:

HashSet<string> anotherHashSet = new HashSet<string>();
foreach (var item in hashSet)
{
    if (!shouldBeRemoved)
    {
        anotherSet.Add(item);
    }
}
hashSet = anotherHashSet;
于 2011-07-20T22:56:57.707 回答
0

通常当我想迭代某些东西并删除我使用的值时:

 For (index = last to first)
      If(ShouldRemove(index)) Then
           Remove(index)
于 2009-09-26T21:40:23.757 回答
0

对于那些正在寻找一种方法来处理 HashSet 中的元素同时删除它们的人,我按照以下方式进行了操作

var set = new HashSet<int> {1, 2, 3};

while (set.Count > 0)
{
  var element = set.FirstOrDefault();
  Process(element);
  set.Remove(element);
}
于 2021-06-29T05:41:36.353 回答