Is there a good way to slice a std::vector
based on elements in a std::set
? In other words, the elements in the std::set
hold the indices that I want in the vector. Certainly, I can accomplish this with the code:
#include <set>
#include <vector>
#include <iostream>
#include <iterator>
template <typename T>
std::vector <T> slice(
std::vector <T> const & x,
std::set <unsigned int> const & I
) {
auto y = std::vector <T> ();
for(auto const & i : I)
y.push_back(x[i]);
return y;
}
int main() {
auto x = std::vector <double> { 1.2, 2.3, 3.4, 4.5, 5.6};
auto I = std::set <unsigned int> { 0, 3, 4};
auto y = slice(x,I);
std::copy(y.begin(),y.end(),std::ostream_iterator <double>(
std::cout,"\n"));
}
which correctly returns
1.2
4.5
5.6
However, this feels a little clumsy. Is there a better way?
You can achieve this by simply using std::transform
:
int main()
{
std::vector<double> x { 1.2, 2.3, 3.4, 4.5, 5.6};
std::set<unsigned int> I { 0, 3, 4};
std::vector<double> y(I.size());
std::transform(I.begin(), I.end(), y.begin(),
[&x](unsigned int i) { return x[i]; });
std::copy(y.begin(),y.end(),std::ostream_iterator <double>(std::cout,"\n"));
}
You could also use std::transform
and std::back_inserter
template <typename T>
std::vector <T> slice(
std::vector<T> const &x,
std::set<unsigned int> const &I)
{
std::vector<double> result;
std::transform(I.begin(), I.end(), std::back_inserter(result),
[&x](unsigned int i) { return x[i]; });
return result;
}
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