Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a vector of pairs from a single vector in C++

I have a single even-sized vector that I want to transform into a vector of pairs where each pair contains always two elements. I know that I can do this using simple loops but I was wondering if there is a nice standard-library tool for this? It can be assumed that the original vector always contains an even amount of elements.

Example:

vector<int> origin {1, 2, 3, 4, 5, 6, 7, 8};

vector<pair<int, int>> goal { {1, 2}, {3, 4}, {5, 6}, {7, 8} };
like image 819
Schottky Avatar asked Sep 12 '25 04:09

Schottky


1 Answers

Use Range-v3:

#include <range/v3/range/conversion.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/chunk.hpp>

using namespace ranges;
using namespace ranges::views;

int main() {
    std::vector<int> origin {1, 2, 3, 4, 5, 6, 7, 8};
    std::vector<std::pair<int, int>> goal {{1, 2}, {3, 4}, {5, 6}, {7, 8}};

    auto constexpr makePairFromRangeOf2 = [](auto two){
        return std::make_pair(two.front(), two.back());
    };

    auto result = origin | chunk(2)
                         | transform(makePairFromRangeOf2)
                         | to_vector;
}

Notice that if you only have to loop on result, then you only need it to be a range, so you can leave | to_vector out, because you'll still be able to do result.begin() and result.end(), which is what makes result a range.

If you don't need the inner containers to truly be std::pairs, but your just happy with calling, say, result.front().front() instead of result.front().first, then you can leave also the transform, and just be happy with auto result = origin | chunk(2);.

You don't mention why you only want a standard solution. However consider that <ranges> is standard in C++20. Unfortunately that feature is not as powerful as pre-C++20 Range-v3 library. But it will be at some point (C++23?), I think without any doubts.

like image 192
Enlico Avatar answered Sep 13 '25 16:09

Enlico