stl <algorithm>: How to delete selectively from vector?

  • Thread starter Alexander Stippler
  • Start date
A

Alexander Stippler

Hello,

I have got a list of indices stored as a stl::vector and a range given by
two iterators, lets say [from, to]. The values in this range are not
ordered, but I have another range of values, lets say lower to upper. Now I
want to remove all values from the stl vector in range [from, to] having
values in [lower, upper]. I have just tried around with remove_if and some
predicates, but I'm not used to the algorithms library. Perhaps someone can
help me.


std::vector<long> indices; // e.g. [1 3 6 2 1 4 6 2 4 1 3 5 7]
^ ^
std::vector<long>::iterator from, to; // e.g. from = indices.begin() + 3,
// to = indices.begin() + 8;
long lower, upper // e.g. lower = 1, upper = 3;


What would it look like?

std::remove_if(from, to, ???????);

regards,
Alex
 
V

Victor Bazarov

Alexander said:
I have got a list of indices stored as a stl::vector and a range given by
two iterators, lets say [from, to]. The values in this range are not
ordered, but I have another range of values, lets say lower to upper. Now I
want to remove all values from the stl vector in range [from, to] having
values in [lower, upper]. I have just tried around with remove_if and some
predicates, but I'm not used to the algorithms library. Perhaps someone can
help me.

Alex, why don't you _get_used_ to the algorithms? Do you have a copy
of Josuttis' "The C++ Standard Library"? If yes, use it. If not, get
it. Today.
std::vector<long> indices; // e.g. [1 3 6 2 1 4 6 2 4 1 3 5 7]
^ ^
std::vector<long>::iterator from, to; // e.g. from = indices.begin() + 3,
// to = indices.begin() + 8;
long lower, upper // e.g. lower = 1, upper = 3;


What would it look like?

std::remove_if(from, to, ???????);

struct MyRemovalPredicate {
long lower, upper;
MyRemovalPredicate(long l, long u) : lower(l), upper(u) {}
bool operator()(long number) const {
return (number >= lower) && (number <= upper);
}
};

....
std::vector<long>::iterator last = std::remove_if(from, to,
MyRemovalPredicate(lower, upper));
indices.erase(to, last); // actually removes them

[Disclaimer: this is all untested, from memory, for illustration only]

V
 
U

Unforgiven

Alexander said:
Hello,

I have got a list of indices stored as a stl::vector and a range
given by two iterators, lets say [from, to]. The values in this range
are not ordered, but I have another range of values, lets say lower
to upper. Now I want to remove all values from the stl vector in
range [from, to] having values in [lower, upper]. I have just tried
around with remove_if and some predicates, but I'm not used to the
algorithms library. Perhaps someone can help me.


std::vector<long> indices; // e.g. [1 3 6 2 1 4 6 2 4 1 3 5 7]
^ ^
std::vector<long>::iterator from, to; // e.g. from =
indices.begin() + 3, //
to = indices.begin() + 8;
long lower, upper // e.g. lower = 1, upper = 3;


What would it look like?

std::remove_if(from, to, ???????);

You need a function or functor to implement your custom predicate:

bool is_in_range(int value)
{
return (value >= lower && value <= upper);
}

then call it as follows:
std::remove_if(from, to, is_in_range);

The problem with that is that lower and upper need to be global. If you want
to set them based on local variables not known at compile time, you need to
use a functor:
class is_in_range
{
public:
is_in_range(long lower, long upper) : _lower(lower), _upper(upper) { }
bool operator() (long value)
{
return (value >= _lower && value <= _upper);
}
private:
long _lower;
long _upper;
};

Then call it as follows:
std::remove_if(from, to, is_in_range(lower, upper));
 
P

Petec

Unforgiven wrote:
Then call it as follows:
std::remove_if(from, to, is_in_range(lower, upper));

That does not actually remove the items, you need this instead:
yourvector.erase(std::remove_if(yourvector.begin(), yourvector.end(),
is_in_range(-10, +10), yourvector.end());

- Pete
 
V

Victor Bazarov

Petec said:
Unforgiven wrote:



That does not actually remove the items, you need this instead:
yourvector.erase(std::remove_if(yourvector.begin(), yourvector.end(),
is_in_range(-10, +10), yourvector.end());

This should probably be

yourvector.erase(
std::remove_if(from, to, is_in_range(lower,upper)), to);

Victor
 
A

Alexander Stippler

Victor said:
Alex, why don't you _get_used_ to the algorithms? Do you have a copy
of Josuttis' "The C++ Standard Library"? If yes, use it. If not, get
it. Today.

First, thanks for your hints. I'm quite interested in the algorithms. But
at the moment I just haven't got the time for an in-depth-study, so I'm
grateful for your help so far. And having a look at the algorithms I already
noticed that they could be helpful in much more places than I thought so
far. So I will definitely have a closer look some (hopefully near) day.

Best regards,
Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top