I have two integer vectors of equal length. Let's say I want to remove all items in the first vector which are NAN. Obviously, I use the remove_if algorithm. Let's say this removes elements that were at indexes 1,2,5. I then want to remove items from the second vector at these indexes.
What's the most canonical C++ way of doing this?
This can be done using Boost by creating a zip_iterator
and then iterating over the tuple
of iterators from both containers in parallel.
First pass a pair of zip_iterators
to std::remove_if
, and have the predicate inspect the elements of the first vector
for NaN
auto result = std::remove_if(boost::make_zip_iterator(boost::make_tuple(v1.begin(), v2.begin())),
boost::make_zip_iterator(boost::make_tuple(v1.end(), v2.end())),
[](boost::tuple<double, int> const& elem) {
return std::isnan(boost::get<0>(elem));
});
Then use vector::erase
to remove the unneeded elements.
v1.erase(boost::get<0>(result.get_iterator_tuple()), v1.end());
v2.erase(boost::get<1>(result.get_iterator_tuple()), v2.end());
Live demo
The boilerplate required to create the zipped iterator ranges can be further reduced by using boost::combine
and Boost.Range's version of remove_if
.
auto result = boost::remove_if(boost::combine(v1, v2),
[](boost::tuple<double, int> const& elem) {
return std::isnan(boost::get<0>(elem));
});
Live demo
Use a vector<pair<int, int>>
to tie the two vector together. Then, perform your remove based on the first element to and get rid of both at the same time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With