Erase some of a vector's elements in a for-each loop without iterating the whole vector

  • A+
Category:Languages

I have a vector and I am searching for an element in it while iterating over the vector with a for-each loop. If I find any invalid elements during the search, I would like to remove them from the vector.

Basically, I want to do something like this:

for (auto el : vec) {     if (el == whatImLookingFor) {         return el;     } else if (isInvalid(el)) {         vec.erase(el);     } } 

I looked at some other questions like this and this, but both recommend using std::remove_if. That will iterate over the whole vector and remove all invalid elements, instead of iterating only until I find the element I'm looking for, and ignoring any elements after that.

What would be a good way to do this?


This is an intuitive approach to the problem that keeps the looping structure - while it only performs a single pass, due to repeated erasing it's likely to be less efficient than a two-pass approach. For this more efficient approach, you should use Benjamin Lindley's answer.


Modifying the code in the answer to the first link you gave, it looks like something like this would fit your specification:

for (auto i = vec.begin(); i != vec.end();) {     if (*i == whatImLookingFor)         return i;     else if (isInvalid(*i))         i = vec.erase(i);     else         ++i; } 
  • If we find the element you're searching for, we return an iterator to it.
  • If we find an invalid element along the way (but not after the desired element), we erase it.
  • We avoid iterator invalidation by keeping the iterator returned from erase.

You'll still need to handle the case where the element's not found, probably by returning vec.end().

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: