Search code examples
c++stlstdvectorstdstd-pair

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} };

Solution

  • 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.