Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > deleting vector elements while looping thru it

Reply
Thread Tools

deleting vector elements while looping thru it

 
 
kaferro@hotmail.com
Guest
Posts: n/a
 
      04-11-2007
What is the typical way to loop through a vector while deleting
certain elements during the loop process? The code below works, but I
am wondering if there is a better solution.


vector<int> vTmp;
vTmp.push_back(1);
vTmp.push_back(2);
vTmp.push_back(1);
vTmp.push_back(2);
vTmp.push_back(1);
vTmp.push_back(1);

for(int x=0; x<vTmp.size(); x++)
{
if(vTmp[x]==1)
{
vTmp.erase(vTmp.begin()+x,vTmp.begin()+x+1);
x--; //to account for new size
}
}

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      04-11-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> What is the typical way to loop through a vector while deleting
> certain elements during the loop process? The code below works, but I
> am wondering if there is a better solution.
>
>
> vector<int> vTmp;
> vTmp.push_back(1);
> vTmp.push_back(2);
> vTmp.push_back(1);
> vTmp.push_back(2);
> vTmp.push_back(1);
> vTmp.push_back(1);
>
> for(int x=0; x<vTmp.size(); x++)
> {
> if(vTmp[x]==1)
> {
> vTmp.erase(vTmp.begin()+x,vTmp.begin()+x+1);
> x--; //to account for new size
> }
> }


vTmp.erase(std::remove_if(vTmp.begin(), vTmp.end(), 1));

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
none
Guest
Posts: n/a
 
      04-11-2007
Victor Bazarov a écrit :
> (E-Mail Removed) wrote:
>> What is the typical way to loop through a vector while deleting
>> certain elements during the loop process? The code below works, but I
>> am wondering if there is a better solution.
>>
>>
>> vector<int> vTmp;
>> vTmp.push_back(1);
>> vTmp.push_back(2);
>> vTmp.push_back(1);
>> vTmp.push_back(2);
>> vTmp.push_back(1);
>> vTmp.push_back(1);
>>
>> for(int x=0; x<vTmp.size(); x++)
>> {
>> if(vTmp[x]==1)
>> {
>> vTmp.erase(vTmp.begin()+x,vTmp.begin()+x+1);
>> x--; //to account for new size
>> }
>> }

>
> vTmp.erase(std::remove_if(vTmp.begin(), vTmp.end(), 1));
>
> V


std::remove_if(vTmp.begin(), vTmp.end(), 1);
should be enough...
--
JF
 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      04-11-2007
none wrote:
> Victor Bazarov a écrit :
>> (E-Mail Removed) wrote:
>>> What is the typical way to loop through a vector while deleting
>>> certain elements during the loop process? The code below works, but I
>>> am wondering if there is a better solution.
>>>
>>>
>>> vector<int> vTmp;
>>> vTmp.push_back(1);
>>> vTmp.push_back(2);
>>> vTmp.push_back(1);
>>> vTmp.push_back(2);
>>> vTmp.push_back(1);
>>> vTmp.push_back(1);
>>>
>>> for(int x=0; x<vTmp.size(); x++)
>>> {
>>> if(vTmp[x]==1)
>>> {
>>> vTmp.erase(vTmp.begin()+x,vTmp.begin()+x+1);
>>> x--; //to account for new size
>>> }
>>> }

>>
>> vTmp.erase(std::remove_if(vTmp.begin(), vTmp.end(), 1));
>>
>> V

>
> std::remove_if(vTmp.begin(), vTmp.end(), 1);
> should be enough...


remove_if doesn't actually remove things, it just reshuffles the
sequence so that the rejected elements are at the end. Having done that,
you have to tell the vector that those elements are no longer part of
the controlled sequence. You do that with erase, passing the iterator
that was returned by remove_if as the start of the sequence to be
erased, and the vector's end iterator as the end.

The proposed code isn't quite right. It should use remove (since its
third argument is a value; remove_if takes a predicate), and it's
missing an end iterator. Should be:

vTmpl.erase(std::remove(vTmp.begin(), vTmp.end(), 1), vTmp.end());

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-11-2007
none" <""jf\"@(none) wrote:
> Victor Bazarov a écrit :
>> (E-Mail Removed) wrote:
>>> What is the typical way to loop through a vector while deleting
>>> certain elements during the loop process? The code below works,
>>> but I am wondering if there is a better solution.
>>>
>>>
>>> vector<int> vTmp;
>>> vTmp.push_back(1);
>>> vTmp.push_back(2);
>>> vTmp.push_back(1);
>>> vTmp.push_back(2);
>>> vTmp.push_back(1);
>>> vTmp.push_back(1);
>>>
>>> for(int x=0; x<vTmp.size(); x++)
>>> {
>>> if(vTmp[x]==1)
>>> {
>>> vTmp.erase(vTmp.begin()+x,vTmp.begin()+x+1);
>>> x--; //to account for new size
>>> }
>>> }

>>
>> vTmp.erase(std::remove_if(vTmp.begin(), vTmp.end(), 1));
>>
>> V

>
> std::remove_if(vTmp.begin(), vTmp.end(), 1);
> should be enough...


No, '1' in that case is not a valid predicate. I messed up. It
ought to be

vTmp.erase(std::remove(vTmp.begin(), vTmp.end(), 1));

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
kaferro@hotmail.com
Guest
Posts: n/a
 
      04-11-2007
I oversimplified my question because I take actions before I erase the
element from the vector.

Revised example code:

vector<cObj> vTmp;
vector<cObj> vErrors;
vTmp.push_back(obj1);
vTmp.push_back(obj2);
vTmp.push_back(obj3);
vTmp.push_back(obj4);

for(int x=0; x<vTmp.size(); x++)
{
if(vTmp[x].returnName=="NA")
{
vErrors.push_back(vTmp[x]);
vTmp.erase(vTmp.begin()+x,vTmp.begin()+x+1);
x--; //to account for new size
}
}

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-11-2007
(E-Mail Removed) wrote:
> I oversimplified my question because I take actions before I erase the
> element from the vector.
>
> Revised example code:
>
> vector<cObj> vTmp;
> vector<cObj> vErrors;
> vTmp.push_back(obj1);
> vTmp.push_back(obj2);
> vTmp.push_back(obj3);
> vTmp.push_back(obj4);
>
> for(int x=0; x<vTmp.size(); x++)
> {
> if(vTmp[x].returnName=="NA")
> {
> vErrors.push_back(vTmp[x]);
> vTmp.erase(vTmp.begin()+x,vTmp.begin()+x+1);
> x--; //to account for new size
> }
> }


struct retNameIs
{
const char* name;
retNameIs(const char* n) : name(n) {}
bool operator()(cObj const& o) {
return o.returnName == name;
}
};

...
vector<cObj> vTmp;
vTmp.push_back(obj1);
vTmp.push_back(obj2);
vTmp.push_back(obj3);
vTmp.push_back(obj4);

vector<cObj>::iterator it =
std::remove_if(vTmp.begin(), vTmp.end(), retNameIs("NA"));
vector<cObj> vErrors(it, vTmp.end());
vTmp.erase(it, vTmp.end());

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Roland Pibinger
Guest
Posts: n/a
 
      04-11-2007
On Wed, 11 Apr 2007 11:17:51 -0400, Pete Becker wrote:
>remove_if doesn't actually remove things, it just reshuffles the
>sequence so that the rejected elements are at the end.


The Standard doesn't specify that 'rejected' elements can be found at
the end of the sequence.



--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-11-2007
Roland Pibinger wrote:
> On Wed, 11 Apr 2007 11:17:51 -0400, Pete Becker wrote:
>> remove_if doesn't actually remove things, it just reshuffles the
>> sequence so that the rejected elements are at the end.

>
> The Standard doesn't specify that 'rejected' elements can be found at
> the end of the sequence.


The algorithm is called "in-place". What besided "reshuffles" can
that mean? 'remove_if' returns the iterator that points to the _end_
of the resulting sequence. What besides placing the "removed"
elements of the sequence beyond the new end could it mean? IOW, if
you apply all the definitions of what 'remove' ('remove_if') does,
it results in moving the rejected elements within the same sequence
beyond what it returns as new end of the sequence.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      04-11-2007
Victor Bazarov wrote:
> Roland Pibinger wrote:
>> On Wed, 11 Apr 2007 11:17:51 -0400, Pete Becker wrote:
>>> remove_if doesn't actually remove things, it just reshuffles the
>>> sequence so that the rejected elements are at the end.

>> The Standard doesn't specify that 'rejected' elements can be found at
>> the end of the sequence.

>
> The algorithm is called "in-place". What besided "reshuffles" can
> that mean?


Actually, he's right, although it's irrelevant to this particular
discussion. remove and remove_if leave whatever junk they fell like at
the end of the original sequence. Typically it's the elements that were
there before, not necessarily the ones that were rejected. So for the
example under discussion, the tail of the array would not hold all 1's
unless they were there to begin with. Typically you'd see a vector
holding, say, 1,3,1,5,7,1 turning into 3,5,7,5,7,1. The last three
elements are the leftovers.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Looping through array, deleting elements dkmd_nielsen Ruby 5 03-08-2007 09:42 PM
Can I dynamically add new elements to vector while looping it? linq936@hotmail.com C++ 7 06-13-2006 01:09 PM
javascript: looping thru elements to find duplicates da_rod_father Java 3 03-18-2006 06:14 AM
Free memory allocate by a STL vector, vector of vector, map of vector Allerdyce.John@gmail.com C++ 8 02-18-2006 12:48 AM
std::vector in vector - LOOPING robk C++ 1 03-25-2005 08:55 PM



Advertisments