4

These are some inputs and relative desired outputs

std::vector<std::string> v1{"aeiou", "bcdfghjk"};
std::vector<std::string> v2{"aeiou", "bcd"};
auto w1 = v1 | wanne_be_transpose;
auto w2 = v2 | wanne_be_transpose;
// w1 = {"ab","ec","id","of","ug","h","j","k"}
// w2 = {"ab","ec","id","o","u"}

Honestly I have no idea how to emulate it with ranges. (Even less in the general case of v1.size() > 2, but my use case is inherently v1.size() == 2, so I'd be ok with a solution only for this case.)

Initially I thought I could ranges::views::zip together and then convert the pairs to inner ranges, but that wouldn't work, because zip's output is as long as the shortest sequence.

Well, in Haskell there's Data.List.transpose:

λ> Data.List.transpose $ ["aeiou","bcdfghjk"]
["ab","ec","id","of","ug","h","j","k"]
λ> Data.List.transpose $ ["aeiou","bcd"]
["ab","ec","id","o","u"]

Coming back to this question after some time, I think I can say that ranges::views::zip or ranges::views::zip_with couldn't be of help in implementing a general transpose operation, because they take a variadiac number of arguments (so a number known at compile time), whereas transpose would have to support a number of ranges know only at run time. The reason is explained in all 3 answers to this question.

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • You wait to get a `zip_longest` adaptor? https://github.com/ericniebler/range-v3/issues/1667 – Tom Huntington Jan 30 '22 at 04:45
  • 1
    @TomHuntington, if `zip_longest` is to be implemented similarly to `zip`/`zip_with`, as in it takes a variadic number of arguments, than it could only marginally help. For instance it'd help in the case of transposing a `range>` where the outer range length is known at compile time (my example, but not before changing `v1` and `v2` to `std::arrays`); but it wouldn't help otherwise. – Enlico Jan 30 '22 at 08:59

1 Answers1

1

Eric Niebler actually implemented the truncating version of this adaptor for his talk demonstrating range-v3 https://www.youtube.com/watch?v=mFUXNMfaciE.

But it didn't make it into range-v3 https://github.com/ericniebler/range-v3/issues/776

However, copy pasting from https://github.com/ericniebler/range-v3/blob/master/example/calendar.cpp we can just do

std::vector<std::string> v1{ "aeiou", "bcdfghjk" };
print2D(v1 | transpose());

https://godbolt.org/z/vj6bbsWso

To get the non-truncating version you could modify the copy pasted code.

Tom Huntington
  • 2,260
  • 10
  • 20