Reputation: 11
The standard way to remove certain elements from a vector in C++ is the remove/erase idiom. However, the predicate passed to remove_if
only takes the vector element under consideration as an argument. Is there a good STL way to do this if the predicate is conditional on other elements of the array?
To give a concrete example, consider removing all duplicates of a number immediately following it. Here the condition for removing the n-th element is conditional on the (n-1)-th element.
Before: 11234555111333
After: 1234513
Upvotes: 1
Views: 951
Reputation: 131799
Others mentioned std::unique
already, for your specific example. Boost.Range has the adjacent_filtered
adaptor, which passes both the current and the next element in the range to your predicate and is, thanks to the predicate, applicable to a larger range of problems. Boost.Range however also has the uniqued
adaptor.
Another possibility would be to simply keep a reference to the range, which is easy to do with a lambda in C++11:
std::vector<T> v;
v.erase(std::remove_if(v.begin(), v.end(),
[&](T const& x){
// use v, with std::find for example
}), v.end());
Upvotes: 2
Reputation: 1103
In my opinion, there will be easier to use simple traversal algorithm(via for) rather then use std::bind. Of course, with std::bind you can use other functions and predicates(which depends on previous elements). But in your example, you can do it via simple std::unique.
Upvotes: 0
Reputation: 55395
There's a standard algorithm for this. std::unique
will remove the elements that are duplicates of those preceding them (actually, just like remove_if
it reorganizes the container so that the elements to be removed are gathered at the end of it).
Example on a std::string
for simplicity:
#include <string>
#include <iostream>
#include <algorithm>
int main()
{
std::string str = "11234555111333";
str.erase(std::unique(str.begin(), str.end()), str.end());
std::cout << str; // 1234513
}
Upvotes: 2