On Jul 23, 12:19 pm, Angus <anguscom...@gmail.comwrote:
I have a vector<int(aRemovecoll) which is a list of the indexes to
be removed from another vector. The other vecotr contains an object -
I will call it SomeObject. So the other vecotr is a
vector<SomeObject>.
I have created a function like this so far:
UINT uNumElements = aRemoveColl.GetSize();
vector<T>::reverse_iterator obCurrent = rbegin(); // work from
end back
for (UINT nLoop = uNumElements; nLoop != 0; nLoop--)
{
// Work from end of vecotr to beginning so that iterators are
always valid
intuIndex;
aRemoveColl.GetAt(nLoop, uIndex);
advance(obCurrent, uIndex);
erase(obCurrent);
}
My thinking is that I need to erase from the end backwards because
otherwise the iterator will become invalid.
Not really.
But then advance doesn't see right.
I don't really understand your code. What's GetAt, for example?
The easiest way to do this would be something like:
for ( std::vector< int >::const_iterator it =
aRemoveColl.begin() ;
it != aRemoveColl.end() ;
++ it ) {
data.erase( data.begin() + *it ) ;
}
You don't remove anything from the vector you're iterating over,
so there is no problem.
Note however that this is O(n*m), with n the number of elements
of data, and m the number of elements to be erased. So you
might want to consider generating into a new vector, or even
defining a predicate for remove_if, and using it. (If
aRemoveColl is sorted, something along the lines of:
class SomeObject ;
class IndexIn
{
public:
typedef std::vector< size_t >
IndexTable ;
typedef std::vector< size_t >::const_iterator
IndexIter ;
explicit IndexIn( IndexTable const& indexes )
: myImpl( new Impl( indexes.begin(), indexes.end() ) )
{
}
bool operator()( SomeObject const& ) const
{
return (*myImpl)() ;
}
private:
class Impl
{
public:
Impl( IndexIter begin, IndexIter end )
: myCurrent( begin )
, myEnd( end )
, myIndex( 0 )
{
}
bool operator()()
{
bool result
= myCurrent != myEnd && myIndex == *myCurrent ;
++ myIndex ;
if ( result ) {
++ myCurrent ;
}
return result ;
}
private:
IndexIter myCurrent ;
IndexIter myEnd ;
size_t myIndex ;
} ;
boost::shared_ptr< Impl>
myImpl ;
} ;
// ...
v.erase( std::remove_if( v.begin(), v.end(),
IndexIn( aRemoveColl ) ),
v.end() ) ;
should do the trick.)
Is there a backward? Or should I be doing this totally
differently?
I'd do it differently.
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34