質問
C# にハッシュセットを反復処理中に条件が満たされた場合に削除するハッシュセットがあり、以下のように foreach ループを使用してこれを行うことができません。
foreach (String hashVal in hashset)
{
if (hashVal == "somestring")
{
hash.Remove("somestring");
}
}
では、反復中に要素を削除するにはどうすればよいでしょうか?
解決
使用 削除場所 代わりに HashSet のメソッド:
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")
十分であろう。複数の一致が存在することはないため、ループで実行する必要はありません。
他のヒント
列挙子を使用してコレクションをループしている間は、コレクションから項目を削除することはできません。これを解決するための 2 つのアプローチは次のとおりです。
- 通常のインデックス付き for ループを使用してコレクションを逆方向にループします (これは、
HashSet
) - コレクションをループし、削除する項目を別のコレクションに追加してから、「削除対象」コレクションをループして項目を削除します。
2 番目のアプローチの例:
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);
}
私は2つのforeachループを使用して避けるだろう - 1つのforeachループで十分です。
HashSet<string> anotherHashSet = new HashSet<string>();
foreach (var item in hashSet)
{
if (!shouldBeRemoved)
{
anotherSet.Add(item);
}
}
hashSet = anotherHashSet;
通常、私は何かを反復処理し、私が使用する値を削除したいときます:
For (index = last to first)
If(ShouldRemove(index)) Then
Remove(index)
所属していません StackOverflow