Reputation: 1685
I have two vectors, of different types, lets say int and double. I also have a third vector with indices and I want to extract the values of the two first vectors corresponding to the indices with range-v3.
Right now I have this
std::vector<int> A {0,1,2,3,4,5,6,7,8};
std::vector<double> B{0,1,2,3,4,5,6,7,8};
std::vector<int> indices{0,2,3};
const std::vector<int> A_slice = indices |
ranges::views::transform([](const auto i) {return 2*i;}) |
ranges::views::transform([&A](const auto i) {return A[i]}) |
ranges::to_vector;
const std::vector<double> B_slice = indices |
ranges::views::transform([](const auto i) {return 2*i;}) |
ranges::views::transform([&B](const auto i) {return B[i]}) |
ranges::to_vector;
This is not the most efficient way, as you need to iterate twice and do the 2*i
transform twice.
One solution would be to get a vector of pairs
const auto AB_slice = indices |
ranges::views::transform([](const auto i) {return 2*i;}) |
ranges::views::transform([&A, &B](const auto i) {return std::make_pair(A[i], B[i]);}) |
ranges::to_vector;
but this is different from two separate vectors. Is there a way to obtain two separate vectors?
Upvotes: 1
Views: 216
Reputation: 141900
So accumulate them yourself, if you want to:
#include <algorithm>
#include <vector>
#include <numeric>
#include <utility>
#include <iostream>
#include <range/v3/all.hpp>
int main() {
std::vector<int> A {0,1,2,3,4,5,6,7,8};
std::vector<double> B{0,1,2,3,4,5,6,7,8};
std::vector<int> indices{0,2,3};
const auto AB_slice = ranges::accumulate(
indices | ranges::views::transform([](const auto i) {return 2*i;}),
std::pair<std::vector<int>, std::vector<double>>(),
[&](std::pair<std::vector<int>, std::vector<double>> v, int i) {
v.first.push_back(A[i]);
v.second.push_back(B[i]);
return std::move(v);
}
);
for (auto i : AB_slice.first) {
std::cout << i << "\n";
}
for (auto i : AB_slice.second) {
std::cout << i << "\n";
}
}
Upvotes: 1