5

I want to split range {1, 2, 3, 4, 5} to range of subranges of <any size> (e.g with size of 2: {{1, 2}, {3, 4}, {5}}). Yet std::views::split only splits by delimiter.

Is there no standard "reverse join" or something to do this?

Barry
  • 286,269
  • 29
  • 621
  • 977
gavrilikhin.d
  • 554
  • 1
  • 7
  • 20
  • To my knowledge, there is not. Loop once through them and create the new arrays.. – Aldert Apr 03 '21 at 06:50
  • 1
    Std::ranges is derived from ranges_v3. You could look if that library offers what you want. However, your use case doesn't seem very general, so probably not. You can always implement your own extention. – JHBonarius Apr 03 '21 at 07:19

1 Answers1

6

range-v3 calls this algorithm chunk. There is no such range adapter in C++20, but it is part of the set being proposed for C++23 under the same name. For example:

#include <vector>
#include <range/v3/view/chunk.hpp>
#include <fmt/format.h>
#include <fmt/ranges.h>

int main() {
    std::vector v = {1, 2, 3, 4, 5};
    fmt::print("{}\n", v | ranges::views::chunk(2)); // prints {{1, 2}, {3, 4}, {5}}
}

This seems to be a pretty consistent choice of name for this algorithm across languages. Python has chunked, Rust has chunks, Swift has chunks(ofCount: n), D has chunks, etc.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • I would mention that if the OP's interest is not just printing to screen with curly braces (they ask about splitting a range, not splitting a range and echoing to terminal), then, while developing, they can more easily rely on the classing `<<` being overloaded for Range-v3's ranges, if they really need to print stuff. – Enlico Apr 03 '21 at 20:15
  • 1
    @Enlico Uh, what? Yeah I understand they asked about "splitting a range, not splitting a range and echoing to terminal" but the latter clearly requires being able to do the former and is the most convenient method for verifying the result. Is there some doubt that the solution I presented actually does what OP requested? – Barry Apr 03 '21 at 22:08
  • 1
    No, no, the solution does answer the question. I'm just implying that you could remove the last two, non-standard, headers in favour of the standard `#include ` and print the result with a simple `std::cout << (v | ranges::views::chunk(2)) << std::endl;`. That would obviously result in `[[1,2],[3,4],[5]]`, with square brackets, rather than curly braces, but probably the OP is not really interested in this cosmetic detail. – Enlico Apr 03 '21 at 23:03
  • Yes, @Enlico has the point. `fmt` is a different topic and, maybe, shouldn't be used in answer on ranges. Yet, I have no problems with it present. – gavrilikhin.d Feb 22 '22 at 12:21