web-dev-qa-db-ja.com

順序付けされていないマップを反復処理しながら複数のアイテムを削除するにはどうすればよいですか?

次の状況を考慮してください。

using namespace std;
unordered_map<int, vector<A>> elements;

今、私はこの順序付けられていないマップを繰り返しています:

for (auto it = elements.begin(); it != elements.end(); ++it)

ループ内では、elementsのいくつかの要素(itが指す現在の要素と、必ずしも次の要素ではない)からクラスターを形成しています。各要素は1つのクラスターの一部にしかなれませんので、それらをマップから削除してから、次の要素に進みます(つまり、次のクラスターを構築します)。

どうすればこれを実行し、正しい位置で反復を続行できますか?

17
Niko
for (auto it = elements.begin(); it != elements.end();) {
   if(you have to rease) {
      it = elements.erase(it);
   }
   else
      it++;
}

このようにして、消去後にインクリメントしないようにし、end()をインクリメントしないようにします。

正当な理由はありません forループがあり、代わりにwhileループが必要なものをインクリメントしないという提案があった後。主に読みやすさのために。

27
user995502

unordered_map::erase は、削除された要素を過ぎたイテレータを返します。

次の行に沿ってコードが必要になります。

it = myMap.erase( it );

重要な注意:ループ内でこれを行う場合は、回避する必要があります。これが行われた場合、ループの最後でのitの一般的な増分。

18
Drew Dormann

erase 関数は、削除された要素の後にイテレータを返します(すべてのコレクションerase関数はそうします)。それを使用して続行できます。

要素を消去する場合は、イテレータを増やさないように注意してください。そうしないと、1つの要素をステップオーバーします。