In List§

See primary documentation in context for routine rotor

method rotor(*@cycle, Bool() :$partial --> Seq:D)

Returns a sequence of lists, where each sublist is made up of elements of the invocant.

In the simplest case, @cycle contains just one integer, in which case the invocant list is split into sublists with as many elements as the integer specifies. If :$partial is True, the final chunk is included even if it doesn't satisfy the length requirement:

say ('a'..'h').rotor(3).join('|');              # OUTPUT: «a b c|d e f␤»
say ('a'..'h').rotor(3, :partial).join('|');    # OUTPUT: «a b c|d e f|g h␤»

If the element of @cycle is a Pair instead, the key of the pair specifies the length of the return sublist, and the value the gap between sublists; negative gaps produce overlap:

say ('a'..'h').rotor(2 => 1).join('|');         # OUTPUT: «a b|d e|g h␤»
say ('a'..'h').rotor(3 => -1).join('|');        # OUTPUT: «a b c|c d e|e f g␤»

If @cycle contains more than element, rotor cycles through it to find the number of elements for each sublist:

say ('a'..'h').rotor(2, 3).join('|');           # OUTPUT: «a b|c d e|f g␤»
say ('a'..'h').rotor(1 => 1, 3).join('|');      # OUTPUT: «a|c d e|f␤»

Combining multiple cycles and :partial also works:

say ('a'..'h').rotor(1 => 1, 3 => -1, :partial).join('|');
# OUTPUT: «a|c d e|e|g h␤»

See this blog post for more elaboration on rotor.

multi rotor(Int:D $batch, \source, Bool() :$partial --> Seq:D)
multi rotor(*@cycle, \source, Bool() :$partial --> Seq:D)

Available as of 6.e language version (early implementation exists in Rakudo compiler 2022.02+).

say rotor(3, 'a'..'h').join('|');             # OUTPUT: «a b c|d e f␤»
say rotor(3, 'a'..'h', :partial).join('|');   # OUTPUT: «a b c|d e f|g h␤»
say rotor(2 => 1, 'a'..'h').join('|');        # OUTPUT: «a b|d e|g h␤»
say rotor(3 => -1, 'a'..'h').join('|');       # OUTPUT: «a b c|c d e|e f g␤»
say rotor(1 => 1, 3 => -1, 'a'..'h', :partial).join('|');
# OUTPUT: «a|c d e|e|g h␤»

In Any§

See primary documentation in context for method rotor

multi method rotor(Any:D: Int:D $batch, :$partial)
multi method rotor(Any:D: *@cycle, :$partial)

Creates a Seq that groups the elements of the object in lists of $batch elements.

say (3..9).rotor(3); # OUTPUT: «((3 4 5) (6 7 8))␤»

With the :partial named argument, it will also include lists that do not get to be the $batch size:

say (3..10).rotor(3, :partial); # OUTPUT: «((3 4 5) (6 7 8) (9 10))␤»

.rotor can be called with an array of integers and pairs, which will be applied in turn. While integers will establish the batch size, as above, Pairs will use the key as batch size and the value as number of elements to skip if it's positive, or overlap if it's negative.

say (3..11).rotor(3, 2 => 1, 3 => -2, :partial);
# OUTPUT: «((3 4 5) (6 7) (9 10 11) (10 11))␤»

In this case, the first batch (ruled by an integer) has 3 elements; the second one has 2 elements (key of the pair), but skips one (the number 8); the third one has size 2 (because partials are allowed), and an overlap of 2 also.

The overlap cannot be larger than the sublist size; in that case, it will throw an Exception:

say (3..11).rotor(3, 2 => 1, 3 => -4, :partial);
# OUTPUT: «(exit code 1) Rotorizing gap is out of range. Is: -4, should be in
# -3..^Inf; ␤Ensure a negative gap is not larger than the length of the
# sublist␤ ␤␤»

Non-Int values of $batch will be coerced to Int:

say (3..9).rotor(3+⅓); # OUTPUT: «((3 4 5) (6 7 8))␤»

Please see also list.rotor for examples applied to lists.

In Supply§

See primary documentation in context for method rotor

method rotor(Supply:D: @cycle --> Supply:D)

Creates a "rotoring" supply with the same semantics as List.rotor.