In List§
See primary documentation in context for routine rotor
method rotor(*, Bool() : --> Seq)
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 , \source, Bool() : --> Seq)
multi rotor(*, \source, Bool() : --> Seq)
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 Supply§
See primary documentation in context for method rotor
method rotor(Supply: --> Supply)
Creates a "rotoring" supply with the same semantics as List.rotor.
In Any§
See primary documentation in context for method rotor
multi method rotor(Any: Int , :)multi method rotor(Any: *, :)
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, Pair
s 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.