Search code examples
c++vectorrange-v3

How to zip vector of vector with range-v3


(This is a follow-on to Sum vector with range-v3)

If I have two (or more) vectors, I can zip them together with range-v3 like this:

std::vector< int > v1{1,1,1};
std::vector< int > v2{2,2,2};

auto v = ranges::views::zip( v1, v2 )
  | ranges::views::transform( ... );

This works well, but in practice, I don't have explicit vectors, but I do have a vector of vectors. I'd like to do the following, but it doesn't give the same result. (In fact, I'm not sure what the result is, and I don't know how to determine what the result is!)


std::vector< std::vector< int > > V{{1,1,1},{2,2,2}};

auto vV = ranges::views::zip( V )
  | ranges::views::transform( ... );

What can I do to zip a vector< vector > like I did to zip a few explicit vectors? I've tried using join along with stride, chunk, etc. but haven't found the magic combination.


Solution

  • I suppose if you don't know the size of external vector in compile time the only reasonable solution that remains is work around it. Instead of trying to zip it I would suggest going with accumulate on top of that as it seems more versatile in this situation.

    std::vector< std::vector< int > > V{{1,1,1},{2,2,2}};
    
    auto vV = ranges::accumulate(
        V,
        std::vector<ResultType>(V[0].size()),
        [](const auto& acc, const auto& next) {
            auto range = ranges::views::zip(acc, next) | ranges::views::transform(...);
            return std::vector<int>(range.begin(), range.end());
        }
    )
    

    EDIT: I forgot the range has to be copied.