Cleanly removing elements from an std::vector

Started by
4 comments, last by Zahlman 18 years, 2 months ago
I'm having trouble figuring out a way to cleanly and efficiently remove elements from a vector. What I'm doing is iterating through a vector, and during the loop, elements may need to be removed, or they may not, and the vector is not sorted. I need to remove the unwanted elements from the middle of the vector, hopefully without stopping looping. When I tried vector.erase(iterator), the program threw a segfault, which I kind of expected :( If I need to do something like loop through the vector backwards and remove values that way, how would I do that? I found a bunch of other kind of iterators, like the reverse_iterator, but I don't understand how to use them. Any tips? Thanks. I would just like the easiest to understand (primarily), and most efficient (secondarily) way to do this.
my siteGenius is 1% inspiration and 99% perspiration
Advertisement
Yeah, the solution is a bit dirty-looking, but it works:
for(it = myVec.begin(); it != myVec.end();){  if(NeedsRemoval(*it))    it = erase(it);  else    ++it;}

The direction you iterate in doesn't matter, since the key issue is that the current iterator is invalidated no matter what.
All right, that'll work. Thanks!
my siteGenius is 1% inspiration and 99% perspiration
Since your elements are not sorted, how about something like this:
MyVec::iterator It (myVec.begin ()) ;MyVec::size_type NElems = myVec.size () ;MyVec::size_type Counter = 0 ;while (Counter != NElems){    //If current element need to be removed        if (NeedsRemoval (*It))        {            (*It) = myVec.back () ; //Save the last element to the current                                    //removing element, to ensure there's no                                    //'hole' in the array            m_Vec.pop_back () ;     //The last element is saved, we may remove                                    //it by now            if (Counter != (NElems - 1))                --NElems ;          //NElems is now decreased by 1, be careful                                    //with this, if we don't have the if                                    //statement, !this is a bug!        }    ++It ;    ++Counter ;}

You may remove duplicate elements in the same loop without invalidating the iterator also.
--> The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones <--
Quote:Original post by Zipster

for(it = myVec.begin(); it != myVec.end();)
{
if(NeedsRemoval(*it))
it = erase(it);
else
++it;
}


#include <algorithm>myVec.erase( std:remove_if( myVec.begin(),myVec.end(), &NeedsRemoval), myVec.end() );


EDIT: forgot a comma

[Edited by - rip-off on January 28, 2006 5:02:11 AM]
Quote:Original post by rip-off
#include <algorithm>myVec.erase( std:remove_if( myVec.begin(),myVec.end(), &NeedsRemoval) myVec.end() );


We have a winner.

This topic is closed to new replies.

Advertisement