An old question but a popular reference so I'm adding another option to this.
The remove_if
function preserves the order of the sequence. That can be very important. However, it can also be a complete waste of time if your program doesn't care about the order.
In order to preserve the order, remove_if
needs to shift the elements down to fill in the removed elements.
Let me introduce partition
. Instead of shifting elements to fill in gaps, it moves an element from the end into the gap. This does not preserve the order, but it can be much faster, especially in a large array.
Here is a sample program:
#include <algorithm>
#include <chrono>
#include <iostream>
#include <iterator>
#include <memory>
#include <string>
#include <vector>
using namespace std;
struct Event {
chrono::nanoseconds delay;
string name;
friend ostream &operator<<(ostream &os, const Event &e) {
return os << "{ \"delay\": " << e.delay.count() << ", \"name\": \""
<< e.name << "\" }";
}
};
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &container) {
bool comma = false;
os << "[ ";
for (const auto &x : container) {
if (comma)
os << ", ";
os << x;
comma = true;
}
os << " ]";
return os;
}
int main() {
vector<Event> iv = {
{0ms, "e1"}, {10ms, "e2"}, {11ms, "e3"}, {0ms, "e4"},
{12ms, "e5"}, {8ms, "e6"}, {13ms, "e7"},
};
iv.erase(partition(begin(iv), end(iv),
[](const auto &x) { return x.delay > 0ns; }),
end(iv));
cout << iv << '\n';
return 0;
}
I compile it on Linux with GCC like so:
g++ -Wall -W -pedantic -g -O3 -std=c++17 partition-test.cpp -o partition-test
And run it:
./partition-test
[ { "delay": 13000000, "name": "e7" }, { "delay": 10000000, "name": "e2" }, { "delay": 11000000, "name": "e3" }, { "delay": 8000000, "name": "e6" }, { "delay": 12000000, "name": "e5" } ]
Let me also introduce a fun command line tool named jq
aka JSON Query:
./partition-test | jq
[
{
"delay": 13000000,
"name": "e7"
},
{
"delay": 10000000,
"name": "e2"
},
{
"delay": 11000000,
"name": "e3"
},
{
"delay": 8000000,
"name": "e6"
},
{
"delay": 12000000,
"name": "e5"
}
]
Which is a pretty great JSON formatter also. Makes it easy to read.
Now you can see that "e7" and "e6" filled in the erased Event objects with delay == 0. And the array is no longer in order.