T M
class List
Error ReportCollection examples

Sequence of values

my class List does Iterable does Positional { }

List stores items sequentially and potentially lazily.

Indexes into lists and arrays start at 0 by default.

You can assign to list elements if they are containers. Use Arrays to have every value of the list stored in a container.

List implements Positional and as such provides support for subscripts.

Immutability

Lists are immutable objects, i.e., neither the number of elements in a list nor the elements themselves can be changed. Thus, it is not possible to use operations that change the list structure itself such as shift, unshift, push, pop, splice and binding.

(123).shift;      # Error Cannot call 'shift' on an immutable 'List' 
(123).unshift(0); # Error Cannot call 'unshift' on an immutable 'List' 
(123).push(4);    # Error Cannot call 'push' on an immutable 'List' 
(123).pop;        # Error Cannot call 'pop' on an immutable 'List' 
(123)[0]:delete;  # Error Cannot remove elements from a List 
(123)[0:= 0;    # Error Cannot use bind operator with this left-hand side 
(123)[0= 0;     # Error Cannot modify an immutable Int 

A List doesn't containerize its elements, but if any element happens to be inside a Scalar container then the element's contents can be replaced via an assignment.

my $a = 'z';
my $list = ($a$'b');
 
say $list[0].VAR.^name# OUTPUT: «Scalar␤», containerized 
say $list[1].VAR.^name# OUTPUT: «Scalar␤», containerized 
say $list[2].VAR.^name# OUTPUT: «Str␤», non-containerized 
 
$list[0= 'a'# OK! 
$list[1= 'c'# OK! 
$list[2= 'd'# Error: Cannot modify an immutable List 

Items, flattening and sigils

In Raku, assigning a List to a scalar variable does not lose information. The difference is that iteration generally treats a list (or any other list-like object, like a Seq or an Array) inside a scalar as a single element.

my $s = (123);
for $s { }      # one iteration 
for $s.list { } # three iterations 
 
my $t = [123];
for $t { }      # one iteration 
for $t.list { } # three iterations 
 
my @a = 123;
for @a { }      # three iterations 
for @a.item { } # one iteration

This operation is called itemization or putting in an item context. .item does the job for objects, as well as $( ... ) and, on array variables, $@a.

Lists generally don't interpolate (flatten) into other lists, except when they are in list context and the single argument to an operation such as append:

my $a = (123);
my $nested = ($a$a);  # two elements 
 
my $flat = $nested.map({ .Slip });  # six elements, with explicit Slip 
 
my @b = <a b>;
@b.append: $a.list;     # The array variable @b has 5 elements, because 
                        # the list $a is the sole argument to append 
 
say @b.elems;           # OUTPUT: «5␤» 
 
my @c = <a b>;
@c.append: $a.list7;  # The array variable @c has 4 elements, because 
                        # the list $a wasn't the only argument and thus 
                        # wasn't flatten by the append operation 
 
say @c.elems;           # OUTPUT: «4␤» 
 
my @d = <a b>;
@d.append: $a;          # The array variable @d has 3 elements, because 
                        # $a is in an item context and as far as append is 
                        # concerned a single element 
 
say @d.elems;           # OUTPUT: «3␤»

The same flattening behavior applies all objects that do the Iterable role, notably hashes:

my %h = => 1=> 2;
my @b = %h;   say @b.elems;     # OUTPUT: «2␤» 
my @c = %h, ; say @c.elems;     # OUTPUT: «1␤» 
my @d = $%h;  say @d.elems;     # OUTPUT: «1␤»

Slurpy parameters (*@a) flatten non-itemized sublists:

sub fe(*@flat{ @flat.elems }
say fe(<a b>, <d e>);           # OUTPUT: «4␤» 
say fe(<a b>, <d e>.item);      # OUTPUT: «3␤»

The empty list is created with (). Smartmatching against the empty list will check for the absence of elements.

my @a;
for @a@a.list@a.Seq -> \listoid {
    say listoid ~~ ()
}
# OUTPUT: «True␤True␤True␤»

Retrieving values from an empty list will always return Nil:

say ()[33.rand]; # OUTPUT: «Nil␤»

Coercion to Bool also indicates if the List got any elements.

my @a;
say [@a.elems@a.Bool?@a]; # OUTPUT: «[0 False False]␤» 
@a.push: 42;
say [@a.elems@a.Bool?@a]; # OUTPUT: «[1 True True]␤» 
say 'empty' unless @a;        # no output

Methods

method ACCEPTS

Defined as:

multi method ACCEPTS(List:D: $topic)

If $topic is an Iterable, returns True or False based on whether the contents of the two Iterables match. A Whatever element in the invocant matches anything in the corresponding position of the $topic Iterable. A HyperWhatever matches any number of any elements, including no elements:

say (123)       ~~ (1,  *3);  # OUTPUT: «True␤» 
say (123)       ~~ (9,  *5);  # OUTPUT: «False␤» 
say (123)       ~~ (   **3);  # OUTPUT: «True␤» 
say (123)       ~~ (   **5);  # OUTPUT: «False␤» 
say (13)          ~~ (1**3); # OUTPUT: «True␤» 
say (12453~~ (1**3); # OUTPUT: «True␤» 
say (12456~~ (1**5); # OUTPUT: «False␤» 
say (12456~~ (   **   ); # OUTPUT: «True␤» 
say ()              ~~ (   **   ); # OUTPUT: «True␤»

In addition, returns False if either the invocant or $topic is a lazy Iterable, unless $topic is the same object as the invocant, in which case True is returned.

If $topic is not an Iterable, returns the invocant if the invocant has no elements or its first element is a Match object (this behavior powers m:g// smartmatch), or False otherwise.

routine elems

Defined as:

sub    elems($list --> Int:D)
method elems(List:D: --> Int:D)

Returns the number of elements in the list.

say (1,2,3,4).elems# OUTPUT: «4␤»

routine end

Defined as:

sub    end($list --> Int:D)
method end(List:D: --> Int:D)

Returns the index of the last element.

say (1,2,3,4).end# OUTPUT: «3␤»

routine keys

Defined as:

sub    keys($list --> Seq:D)
method keys(List:D: --> Seq:D)

Returns a sequence of indexes into the list (e.g., 0..(@list.elems-1)).

say (1,2,3,4).keys# OUTPUT: «0..3␤»

routine values

Defined as:

sub    values($list --> Seq:D)
method values(List:D: --> Seq:D)

Returns a sequence of the list elements, in order.

say (1,2,3,4).^name;        # OUTPUT: «List␤» 
say (1,2,3,4).values.^name# OUTPUT: «Seq␤»

routine kv

Defined as:

sub    kv($list --> Seq:D)
method kv(List:D: --> Seq:D)

Returns an interleaved sequence of indexes and values. For example

say <a b c>.kv# OUTPUT: «(0 a 1 b 2 c)␤»

routine pairs

Defined as:

sub    pairs($list --> Seq:D)
method pairs(List:D: --> Seq:D)

Returns a sequence of pairs, with the indexes as keys and the list values as values.

say <a b c>.pairs;   # OUTPUT: «(0 => a 1 => b 2 => c)␤»

routine antipairs

Defined as:

method antipairs(List:D: --> Seq:D)

Returns a Seq of pairs, with the values as keys and the indexes as values, i.e. the direct opposite to pairs.

say <a b c>.antipairs;  # OUTPUT: «(a => 0 b => 1 c => 2)␤»

routine invert

Defined as:

method invert(List:D: --> Seq:D)

Assumes every element of the List is a Pair. Returns all elements as a Seq of Pairs where the keys and values have been exchanged. If the value of a Pair is an Iterable, then it will expand the values of that Iterable into separate pairs.

my $l = List.new('a' => (23), 'b' => 17);
say $l.invert;   # OUTPUT: «(2 => a 3 => a 17 => b)␤»

routine join

Defined as:

sub    join($separator*@list)
method join(List:D: $separator = "")

Treats the elements of the list as strings by calling .Str on each of them, interleaves them with $separator and concatenates everything into a single string.

Example:

say join '', <a b c>;             # OUTPUT: «a, b, c␤»

The method form also allows you to omit the separator:

say <a b c>.join;               # OUTPUT: «abc␤»

Note that the method form does not flatten sublists:

say (1, <a b c>).join('|');     # OUTPUT: «1|a b c␤»

The subroutine form behaves slurpily, flattening all arguments after the first into a single list:

say join '|'1, <a b c>;       # OUTPUT: «1|a|b|c␤»

In this case, the list <a b c> is slurped and flattened, unlike what happens when join is invoked as a method.

If one of the elements of the list happens to be a Junction, then join will also return a Junction with concatenation done as much as possible:

say ("a"|"b","c","d").join;     # OUTPUT: «any(acd,bcd)␤»

routine map

Defined as:

multi method map(Hash:D \hash)
multi method map(Iterable:D \iterable)
multi method map(|c)
multi method map(\SELF: &block;; :$label:$item)
multi sub map(&code+values)

Examples applied to lists are included here for the purpose of illustration.

For a list, it invokes &code for each element and gathers the return values in a sequence and returns it. This happens lazily, i.e. &code is only invoked when the return values are accessed.Examples:

say ('hello'122/742'world').map: { .^name } # OUTPUT: «(Str Int Rat Int Str)␤» 
say map *.Str.chars'hello'122/742'world'# OUTPUT: «(5 1 8 2 5)␤» 

map inspects the arity of the code object, and tries to pass as many arguments to it as expected:

sub b($a$b{ "$a before $b" };
say <a b x y>.map(&b).join('');   # OUTPUT: «a before b, x before y␤»

iterates the list two items at a time.

Note that map does not flatten embedded lists and arrays, so

((12), <a b>).map({ .join(',')})

passes (1, 2) and <a b> in turn to the block, leading to a total of two iterations and the result sequence "1,2", "a,b". See method flatmap for an alternative that flattens.

If &code is a Block loop phasers will be executed and loop control statements will be treated as in loop control flow. Please note that return is executed in the context of its definition. It is not the return statement of the block but the surrounding Routine. Using a Routine will also handle loop control statements and loop phasers. Any Routine specific control statement or phaser will be handled in the context of that Routine.

sub s {
    my &loop-block = {
        return # return from sub s 
    };
    say 'hi';
    (1..3).map: &loop-block;
    say 'oi‽' # dead code 
};
s 
# OUTPUT: «hi␤»

method flatmap

Defined as:

method flatmap(List:D: &code --> Seq:D)

Like map iterates over the elements of the invocant list, feeding each element in turn to the code reference, and assembling the return values from these invocations in a result list.

The use of flatmap is strongly discouraged. Instead of .flatmap( ), please use .map( ).flat as it is clear when the .flat is called and is not confusing like .flatmap.

Unlike map it flattens non-itemized lists and arrays, so

## flatmap 
my @list = ('first1', ('second2', ('third3''third4'), 'second5'), 'first6');
say @list.flatmap({.reverse}).raku;
# OUTPUT: «("first1", "second5", "third3", "third4", "second2", "first6").Seq␤» 
## map 
say @list.map({"$_ was a {.^name}"}).raku;
# OUTPUT: «("first1 was a Str", "second2 third3 third4 second5 was a List", "first6 was a Str").Seq␤» 
## .map .flat has the same output as .flatmap 
say @list.map({.reverse}).flat.raku;
# OUTPUT: «("first1", "second5", "third3", "third4", "second2", "first6").Seq␤»

method gist

Defined as:

multi method gist(List:D: --> Str:D)

Returns the string containing the parenthesized "gist" of the List, listing up to the first 100 elements, separated by space, appending an ellipsis if the List has more than 100 elements. If List is-lazy, returns string '(...)'

put (123).gist;   # OUTPUT: «(1 2 3)␤» 
put (1..∞).List.gist# OUTPUT: «(...)␤» 
 
put (1..200).List.gist;
# OUTPUT: 
# (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 
# 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 
# 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 
# 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 
# 96 97 98 99 100 ...) 

routine grep

Defined as:

sub    grep(Mu $matcher*@elems:$k:$kv:$p:$v --> Seq:D)
method grep(List:D:  Mu $matcher:$k:$kv:$p:$v --> Seq:D)

Returns a sequence of elements against which $matcher smartmatches. The elements are returned in the order in which they appear in the original list.

Examples:

say ('hello'122/742'world').grep: Int;              # OUTPUT: «(1 42)␤» 
say grep { .Str.chars > 3 }'hello'122/742'world'# OUTPUT: «(hello 3.142857 world)␤»

Note that if you want to grep for elements that do not match, you can use a none-Junction:

say <a b 6 d 8 0>.grep(none Int);           # OUTPUT: «(a b d)␤» 
say <a b c d e f>.grep(none /<[aeiou]>/);   # OUTPUT: «(b c d f)␤»

Another option to grep for elements that do not match a regex is to use a block:

say <a b c d e f>.grep({! /<[aeiou]>/})     # OUTPUT: «(b c d f)␤»

The reason the example above works is because a regex in Boolean context applies itself to $_. In this case, ! boolifies the /<[aeiou]>/ regex and negates the result. Smartmatching against a Callable (in this case a Block) returns the value returned from that callable, so the boolified result of a regex is then used to decide whether the current value should be kept in the result of a grep.

The optional named parameters :k, :kv, :p, :v provide the same functionality as on slices:

  • k

Only return the index values of the matching elements in order.

  • kv

Return both the index and matched elements in order.

  • p

Return the index and the matched element as a Pair, in order.

  • v

Only return the matched elements (same as not specifying any named parameter at all).

Examples:

say ('hello'122/742'world').grep: Int:k;
# OUTPUT: «(1 3)␤» 
say grep { .Str.chars > 3 }:kv'hello'122/742'world';
# OUTPUT: «(0 hello 2 3.142857 4 world)␤» 
say grep { .Str.chars > 3 }:p'hello'122/742'world';
# OUTPUT: «(0 => hello 2 => 3.142857 4 => world)␤»

routine first

Defined as:

sub    first(Mu $matcher*@elems:$k:$kv:$p:$end)
method first(List:D:  Mu $matcher?:$k:$kv:$p:$end)

Returns the first item of the list which smartmatches against $matcher, returns Nil when no values match. The optional named parameter :end indicates that the search should be from the end of the list, rather than from the start.

Examples:

say (122/742300).first: * > 5;                  # OUTPUT: «42␤» 
say (122/742300).first: * > 5:end;            # OUTPUT: «300␤» 
say ('hello'122/742'world').first: Complex;   # OUTPUT: «Nil␤»

The optional named parameters :k, :kv, :p provide the same functionality as on slices:

  • k

Return the index value of the matching element. Index is always counted from the beginning of the list, regardless of whether the :end named parameter is specified or not.

  • kv

Return both the index and matched element.

  • p

Return the index and the matched element as a Pair.

Examples:

say (122/742300).first: * > 5:k;        # OUTPUT: «2␤» 
say (122/742300).first: * > 5:p;        # OUTPUT: «2 => 42␤» 
say (122/742300).first: * > 5:kv:end# OUTPUT: «(3 300)␤»

In method form, the $matcher can be omitted, in which case the first available item (or last if :end is set) will be returned. See also head and tail methods.

method head

Defined as:

multi method head(Any:D:is raw
multi method head(Any:D: Callable:D $w)
multi method head(Any:D: $n)

This method is directly inherited from Any, and it returns the first $n items of the list, an empty list if $n <= 0, or the first element with no argument. The version that takes a Callable uses a WhateverCode to specify all elements, starting from the first, but the last ones.

Examples:

say <a b c d e>.head ;     # OUTPUT: «a␤» 
say <a b c d e>.head(2);   # OUTPUT: «(a b)␤» 
say <a b c d e>.head(*-3); # OUTPUT: «(a b)␤»

method tail

Defined as:

multi method tail(List:D:)
multi method tail(List:D: $n --> Seq:D)

Returns a Seq containing the last $n items of the list. Returns an empty Seq if $n <= 0. Defaults to the last element if no argument is specified. Throws an exception if the list is lazy.

Examples:

say <a b c d e>.tail(*-3);# OUTPUT: «(d e)␤» 
say <a b c d e>.tail(2);  # OUTPUT: «(d e)␤» 
say <a b c d e>.tail;     # OUTPUT: «e␤» 

In the first case, $n is taking the shape of a WhateverCode to indicate the number of elements from the beginning that will be excluded. $n can be either a Callable, in which case it will be called with the value 0, or anything else that can be converted to a number, in which case it will use that as the number of elements in the output Seq.

say <a b c d e>.tail{ $_ - 2 } ); # OUTPUT: «(c d e)␤»

routine categorize

Defined as:

multi method categorize()
multi method categorize(Whatever)
multi method categorize($test:$into!:&as)
multi method categorize($test:&as)
multi sub categorize($test+items:$into!*%named )
multi sub categorize($test+items*%named )

These methods are directly inherited from Any; see Any.list for more examples.

This routine transforms a list of values into a hash representing the categorizations of those values according to $test, which is called once for every element in the list; each hash key represents one possible categorization for one or more of the incoming list values, and the corresponding hash value contains an array of those list values categorized by the $test, acting like a mapper, into the category of the associated key.

Note that, unlike classify, which assumes that the return value of the mapper is a single value, categorize always assumes that the return value of the mapper is a list of categories that are appropriate to the current value.

Example:

sub mapper(Int $ireturns List {
    $i %% 2 ?? 'even' !! 'odd',
    $i.is-prime ?? 'prime' !! 'not prime'
}
say categorize &mapper, (17632);
# OUTPUT: «{even => [6 2], not prime => [1 6], odd => [1 7 3], prime => [7 3 2]}␤»

routine classify

Defined as:

multi method classify($test:$into!:&as)
multi method classify($test:&as)
multi sub classify($test+items:$into!*%named )
multi sub classify($test+items*%named )

Transforms a list of values into a hash representing the classification of those values; each hash key represents the classification for one or more of the incoming list values, and the corresponding hash value contains an array of those list values classified into the category of the associated key. $test will be an expression that will produce the hash keys according to which the elements are going to be classified.

Example:

say classify { $_ %% 2 ?? 'even' !! 'odd' }, (17632);
# OUTPUT: «{even => [6 2], odd => [1 7 3]}␤» 
say ('hello'122/742'world').classify: { .Str.chars };
# OUTPUT: «{1 => [1], 2 => [42], 5 => [hello world], 8 => [3.142857]}␤»

It can also take :as as a named parameter, transforming the value before classifying it:

say <Innie Minnie Moe>.classify{ $_.chars }:as{ lc $_ });
# OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»

This code is classifying by number of characters, which is the expression that has been passed as $test parameter, but the :as block lowercases it before doing the transformation. The named parameter :into can also be used to classify into a newly defined variable:

<Innie Minnie Moe>.classify{ $_.chars }:as{ lc $_ }:intomy %words{Int} ) );
say %words# OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»

We are declaring the scope of %words{Int} on the fly, with keys that are actually integers; it gets created with the result of the classification.

method Bool

Defined as:

method Bool(List:D: --> Bool:D)

Returns True if the list has at least one element, and False for the empty list.

say ().Bool;  # OUTPUT: «False␤» 
say (1).Bool# OUTPUT: «True␤»

method Str

Defined as:

method Str(List:D: --> Str:D)

Stringifies the elements of the list and joins them with spaces (same as .join(' ')).

say (1,2,3,4,5).Str# OUTPUT: «1 2 3 4 5␤»

method Int

Defined as:

method Int(List:D: --> Int:D)

Returns the number of elements in the list (same as .elems).

say (1,2,3,4,5).Int# OUTPUT: «5␤»

method Numeric

Defined as:

method Numeric(List:D: --> Int:D)

Returns the number of elements in the list (same as .elems).

say (1,2,3,4,5).Numeric# OUTPUT: «5␤»

method Capture

Defined as:

method Capture(List:D: --> Capture:D)

Returns a Capture where each Pair, if any, in the List has been converted to a named argument (with the key of the Pair stringified). All other elements in the List are converted to positional arguments in the order they are found, i.e. the first non pair item in the list becomes the first positional argument, which gets index 0, the second non pair item becomes the second positional argument, getting index 1 etc.

my $list = (75=> 2=> 17);
my $capture = $list.Capture;
say $capture.keys;                                # OUTPUT: «(0 1 a b)␤» 
my-sub(|$capture);                                # OUTPUT: «7, 5, 2, 17» 
 
sub my-sub($first$second:$a:$b{
    say "$first$second$a$b"
}

A more advanced example demonstrating the returned Capture being matched against a Signature.

my $list = (75=> 2=> 17);
say so $list.Capture ~~ :($ where * == 7,$,:$a,:$b); # OUTPUT: «True␤» 
 
$list = (85=> 2=> 17);
say so $list.Capture ~~ :($ where * == 7,$,:$a,:$b); # OUTPUT: «False␤»

routine pick

Defined as:

multi sub    pick($count*@list --> Seq:D)
multi method pick(List:D: $count --> Seq:D)
multi method pick(List:D: --> Mu)

If $count is supplied: Returns $count elements chosen at random and without repetition from the invocant. If * is passed as $count, or $count is greater than or equal to the size of the list, then all elements from the invocant list are returned in a random sequence; i.e. they are returned shuffled.

In method form, if $count is omitted: Returns a single random item from the list, or Nil if the list is empty

Examples:

say <a b c d e>.pick;           # OUTPUT: «b␤» 
say <a b c d e>.pick: 3;        # OUTPUT: «(c a e)␤» 
say <a b c d e>.pick: *;        # OUTPUT: «(e d a b c)␤»

routine roll

Defined as:

multi sub    roll($count*@list --> Seq:D)
multi method roll(List:D: $count --> Seq:D)
multi method roll(List:D: --> Mu)

If $count is supplied: Returns a sequence of $count elements, each randomly selected from the list. Each random choice is made independently, like a separate die roll where each die face is a list element. If * is passed as $count returns a lazy, infinite sequence of randomly chosen elements from the original list.

If $count is omitted: Returns a single random item from the list, or Nil if the list is empty

Examples:

say <a b c d e>.roll;       # 1 random letter 
say <a b c d e>.roll: 3;    # 3 random letters 
say roll 8, <a b c d e>;    # 8 random letters 
 
my $random-digits := (^10).roll(*);
say $random-digits[^15];    # 15 random digits

routine eager

Defined as:

multi method eager(List:D: --> List:D)
multi sub eager(*@elems --> List:D)

Evaluates all elements in the List eagerly, and returns them as a List.

my  \ll = (lazy 1..5).cache;
 
say ll[];     # OUTPUT: «(...)␤» 
say ll.eager  # OUTPUT: «(1 2 3 4 5)␤»

routine reverse

Defined as:

multi sub    reverse(*@list  --> Seq:D)
multi method reverse(List:D: --> Seq:D)

Returns a Seq with the same elements in reverse order.

Note that reverse always refers to reversing elements of a list; to reverse the characters in a string, use flip.

Examples:

say <hello world!>.reverse;     # OUTPUT: «(world! hello)␤» 
say reverse ^10;                # OUTPUT: «(9 8 7 6 5 4 3 2 1 0)␤»

routine rotate

Defined as:

multi sub    rotate(@list,  Int:D $n = 1 --> Seq:D)
multi method rotate(List:D: Int:D $n = 1 --> Seq:D)

Returns a Seq with the list elements rotated to the left when $n is positive or to the right otherwise.

Examples:

say <a b c d e>.rotate(2);   # OUTPUT: (c d e a b) 
say <a b c d e>.rotate(-1);  # OUTPUT: (e a b c d)

Note: Before Rakudo version 2020.06 a new List was returned instead of a Seq.

routine sort

Defined as:

multi sub    sort(*@elems      --> Seq:D)
multi sub    sort(&custom-routine-to-use*@elems --> Seq:D)
multi method sort(List:D:      --> Seq:D)
multi method sort(List:D: &custom-routine-to-use  --> Seq:D)

Sorts the list, smallest element first. By default infix:<cmp> is used for comparing list elements.

If &custom-routine-to-use is provided, and it accepts two arguments, it is invoked for pairs of list elements, and should return Order::Less, Order::Same or Order::More.

If &custom-routine-to-use accepts only one argument, the list elements are sorted according to custom-routine-to-use($a) cmp custom-routine-to-use($b) . The return values of &custom-routine-to-use are cached, so that &custom-routine-to-use is only called once per list element.

Examples:

say (3-47-120).sort;                  # OUTPUT: «(-4 -1 0 2 3 7)␤» 
say (3-47-120).sort: *.abs;           # OUTPUT: «(0 -1 2 3 -4 7)␤» 
say (3-47-120).sort: { $^b leg $^a }# OUTPUT: «(7 3 2 0 -4 -1)␤»

Additionally, if &custom-routine-to-use returns a List, elements will be sorted based upon multiple values with subsequent values in the List being used to break the tie if the comparison between the prior elements evaluate to Order::Same.

my @resistance = (
    %first-name => 'Kyle',  last-name => 'Reese'  ),
    %first-name => 'Sarah'last-name => 'Connor' ),
    %first-name => 'John',  last-name => 'Connor' ),
);
.say for @resistance.sort: { .<last-name>.<first-name> };
 
#`(
OUTPUT:
  {first-name => John, last-name => Connor}
  {first-name => Sarah, last-name => Connor}
  {first-name => Kyle, last-name => Reese}
)

This sorting can be based on characteristics of a single element:

say <ddd aaa bbb bb ccc c>.sort{.chars.Str} );
# OUTPUT: «(c bb aaa bbb ccc ddd)␤» 

In this case, elements of the array are sorted in ascending order according first to the string length (.chars) and second to the actual alphabetical order .Str) if the length is exactly the same.

Any number of criteria can be used in this:

say <01 11 111 2 20 02>.sort{ .Int.comb.sum.Str } );
# OUTPUT: «(01 02 2 11 20 111)␤» 

routine reduce

Defined as:

multi method reduce(Any:D: &with)
multi sub reduce (&with+list)

Returns a single "combined" value from a list of arbitrarily many values, by iteratively applying a routine which knows how to combine two values. In addition to the subroutine and the list, an initial value can be provided to initialize the reduction, which ends up being the return value if the list is empty. Thus reduce f, init, list combines the elements of the list from left to right, as is shown in the following pseudocode:

result0 = init
result1 = f(result0list[0])
result2 = f(result1list[1])
...
resultn = f(resultn-1, list[n-1])

resultn is the final result for an n-element list.

say reduce &infix:<+>, (123); # OUTPUT: «6␤» 
say (123).reduce: &infix:<+># OUTPUT: «6␤» 
say reduce &max, (59121);   # OUTPUT: «12␤»

If list contains just a single element, the operator is applied to that single element if possible; if not, it returns the element itself.

say reduce &infix:<->, (10,);     # OUTPUT: «10␤»

When the list contains no elements, an exception is thrown, unless &with is an operator with a known identity value (e.g., the identity value of infix:<+> is 0). For this reason, you're advised to prefix the input list with an initial value (or explicit identity value):

my \strings = "One good string!""And one another good string!";
say reduce { $^a ~ $^b }''|strings;               # like strings.join 
 
my \numbers = 12345;
say reduce { $^a > $^b ?? $^a !! $^b }0|numbers# like numbers.max 
 
sub count-and-sum-evens( (Int \countInt \sum), Int \x ) {
    x %% 2 ?? (count+1, sum+x!! (countsum)
}
 
say reduce &count-and-sum-evens, (00), |numbers;    # OUTPUT: «(2 6)␤»

In the last example, since reduce only supports one initial value we use a List with two values, which is by itself a single value. The count-and-sum-evens subroutine takes two positional values: a List of two Ints and an Int, and return a List storing the count and sum of the even integers accumulated.

If &with is the code object of an operator, its inherent identity value and associativity is respected - in other words, (VAL1, VAL2, VAL3).reduce(&infix:<OP>) is the same as VAL1 OP VAL2 OP VAL3 even for operators which aren't left-associative:

# Raise 2 to the 81st power, because 3 to the 4th power is 81 
(2,3,4).reduce(&infix:<**>).lsb.say;  # OUTPUT: «81␤» 
(2**(3**4)).lsb.say;                  # OUTPUT: «81␤» 
(2**3**4).lsb.say;                    # OUTPUT: «81␤» 
 
# Subtract 4 from -1, because 2 minus 3 is -1 
(2,3,4).reduce(&infix:<->).say;       # OUTPUT: «-5␤» 
((2-3)-4).say;                        # OUTPUT: «-5␤» 
(2-3-4).say;                          # OUTPUT: «-5␤»

Since reducing with an infix operator is a common thing to do, the reduction metaoperator [ ] provides a syntactic shortcut. Thus, instead of passing the operator's code object to reduce, just pass the operator directly to [ ]. To use a user-defined subroutine instead, provide an additional layer of square brackets around the subroutine's code object:

say [*] (1234);       # OUTPUT: «24␤» 
say [min] (4213);     # OUTPUT: «1␤» 
 
sub mult { $^a * $^b };
say [[&mult]] (1234); # OUTPUT: «24␤»

Semantically, all the following do the same thing:

my \numbers = 12345;
say reduce { $^a + $^b }0|numbers;
say reduce * + *0|numbers;
say reduce &[+], numbers# operator does not need explicit identity value 
say [+numbers;

Since reduce is an implicit loop that iterates over with its reducing subroutine, it responds to next, last and redo statements inside &with:

sub last-after-seven { last if $^a > 7$^a + $^b };
say (2345).reduce: &last-after-seven# OUTPUT: «9␤»

Whether reduce accumulates the elements starting from the left or from the right depends on the operator. In the functional programming world, this operation is generally called a fold. With a right-associative operator it is a right fold, otherwise (and usually) it is a left fold. In Raku, you can specify the associativity of an operator with the is assoc.

sub infix:<foo>($a$bis assoc<right> { "($a$b)" }
say [foo1234# OUTPUT: «(1, (2, (3, 4)))␤» 
 
sub infix:<bar>($a$bis assoc<left> { "($a$b)" }
say [bar1234# OUTPUT: «(((1, 2), 3), 4)␤»

Practical example 1: In this example, we generate a random-ish math formula (e.g., "(4 + ((3 * x) + 11) / 6))") using reduce.

my @ops = [Z] (<+ - * />1..20.roll(4);
 
say ('x'|@ops).reduce: -> $formula, [$op$number{
    Bool.pick ?? "($formula $op $number)"
              !! "($number $op $formula)"
}

Practical example 2: Suppose we have a polynomial represented as a list of integer coefficients, c[n-1], c[n-2], ..., c[0], where c[i] is the coefficient of xi. We can evaluate it using map and reduce as follows:

sub evaluate(List:D \c where c.all ~~ IntRat:D \x --> Rat:D{
    my \xi = (c.elems ^... 0).map: -> \i { x ** i }# [x^(n-1), ..., x^0] 
    my \axi = [+c Z* xi;                           # [c[n-1]*x^(n-1), ..., c[*]x^0] 
    [+axi;                                         # sum of axi 
}
 
my \c = 231;       # 2x² + 3x + 1 
say evaluate c3.0;   # OUTPUT: «28␤» 
say evaluate c10.0;  # OUTPUT: «231␤»

routine produce

Defined as:

multi sub    produce(&with*@values)
multi method produce(List:D: &with)

Generates a list of all intermediate "combined" values along with the final result by iteratively applying a function which knows how to combine two values.

If @values contains just a single element, a list containing that element is returned immediately. If it contains no elements, an exception is thrown, unless &with is an operator with a known identity value.

If &with is the function object of an operator, its inherent identity value and associativity is respected - in other words, (VAL1, VAL2, VAL3).produce(&[OP]) is the same as VAL1 OP VAL2 OP VAL3 even for operators which aren't left-associative:

# Raise 2 to the 81st power, because 3 to the 4th power is 81 
[2,3,4].produce(&[**]).say;        # OUTPUT: «(4 81 2417851639229258349412352)␤» 
say produce &[**], (2,3,4);        # OUTPUT: «(4 81 2417851639229258349412352)␤» 
say [\**] (2,3,4);                 # OUTPUT: «(4 81 2417851639229258349412352)␤» 
 
# Subtract 4 from -1, because 2 minus 3 is -1 
[2,3,4].produce(&[-]).say;         # OUTPUT: «(2 -1 -5)␤» 
say produce &[-], (2,3,4);         # OUTPUT: «(2 -1 -5)␤» 
say [\-] (2,3,4);                  # OUTPUT: «(2 -1 -5)␤»

A triangle metaoperator [\ ] provides a syntactic shortcut for producing with an infix operator:

# The following all do the same thing... 
my @numbers = (1,2,3,4,5);
say produce { $^a + $^b }@numbers;
say produce * + *@numbers;
say produce &[+], @numbers# operator does not need explicit identity 
say [\+@numbers;          # most people write it this way

The visual picture of a triangle [\ is not accidental. To produce a triangular list of lists, you can use a "triangular comma":

[\,] 1..5;
# ( 
# (1) 
# (1 2) 
# (1 2 3) 
# (1 2 3 4) 
# (1 2 3 4 5) 
# )

Since produce is an implicit loop, it responds to next, last and redo statements inside &with:

say (2,3,4,5).produce: { last if $^a > 7$^a + $^b }# OUTPUT: «(2 5 9)␤»

routine combinations

Defined as:

multi sub    combinations($from$of = 0..*             --> Seq:D)
multi method combinations(List:D: Int() $of             --> Seq:D)
multi method combinations(List:D: Iterable:D $of = 0..* --> Seq:D)

Returns a Seq with all $of-combinations of the invocant list. $of can be a numeric Range, in which case combinations of the range of item numbers it represents will be returned (i.e. 2.6 .. 4 will return 2-, 3-, and 4-item combinations). Otherwise, $of is coerced to an Int.

.say for <a b c>.combinations: 2;
# OUTPUT: 
# (a b) 
# (a c) 
# (b c)

Above, there are three possible ways to combine the 2-items lists from the original list, which is what we receive in the output. See permutations if you want permutations instead of combinations.

With Range argument, we get both three 2-item combinations and one 3-item combination:

.say for <a b c>.combinations: 2..3;
# OUTPUT: 
# (a b) 
# (a c) 
# (b c) 
# (a b c)

If $of is negative or is larger than there are items in the given list, an empty list will be returned. If $of is zero, a 1-item list containing an empty list will be returned (there's exactly 1 way to pick no items).

The subroutine form is equivalent to the method form called on the first argument ($from), with the exception that if $from is not an Iterable, it gets coerced to an Int and combinations are made from a Range constructed with 0..^$from instead:

.say for combinations 32
# OUTPUT: 
# (0 1) 
# (0 2) 
# (1 2)

Note: some implementations may limit the maximum value of non-Iterable $from. On Rakudo, 64-bit systems have a limit of 2³¹-1 and 32-bit systems have a limit of 2²⁸-1.

routine permutations

Defined as:

multi sub    permutations(Int()    $from --> Seq:D)
multi sub    permutations(Iterable $from --> Seq:D)
multi method permutations(List:D:        --> Seq:D)

Returns all possible permutations of a list as a Seq of lists:

.say for <a b c>.permutations;
# OUTPUT: 
# (a b c) 
# (a c b) 
# (b a c) 
# (b c a) 
# (c a b) 
# (c b a)

permutations treats all elements as unique, thus (1, 1, 2).permutations returns a list of 6 elements, even though there are only three distinct permutations, due to first two elements being the same.

The subroutine form behaves the same as the method form, computing permutations from its first argument $from. If $from is not an Iterable, coerces $from to an Int and picks from a Range constructed with 0..^$from:

.say for permutations 3;
# OUTPUT: 
# (0 1 2) 
# (0 2 1) 
# (1 0 2) 
# (1 2 0) 
# (2 0 1) 
# (2 1 0)

method rotor

Defined as:

method rotor(*@cycleBool() :$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(23).join('|');           # OUTPUT: «a b|c d e|f g␤» 
say ('a'..'h').rotor(1 => 13).join('|');      # OUTPUT: «a|c d e|f␤»

Combining multiple cycles and :partial also works:

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

See this blog post for more elaboration on rotor.

method batch

Defined As:

multi method batch(Int:D $batch --> Seq)
multi method batch(Int:D :$elems --> Seq)

Returns a sequence of lists, wherein each list with the exception of the last one is guaranteed to comprise a number of elements equal to the batch size specified by $batch or $elems, respectively. If the invocant has a number of elements that is not an integer multiple of the batch size, the last list in the returned sequence will contain any remaining elements and thus have less than $batch or $elems elements. Accordingly, .batch($batch) is shorthand for .rotor($batch, :partial).

routine cross

sub cross(+@e:&with --> Seq:D)

Computes the cross-product of two or more lists or iterables. This returns a sequence of lists where the first item in each list is an item from the first iterable, the second is from the second given iterable, etc. Every item will be paired with every other item in all the other lists.

say cross(<a b c>, <d e f>).map(*.join).join(",")
# OUTPUT: «ad,ae,af,bd,be,bf,cd,ce,cf␤»

The cross routine has an infix synonym as well, named X.

say (<a b c> X <d e f>).map(*.join).join(",")
# output is the same as the previous example

If the optional with parameter is passed, it is used as a reduction operation to apply to each of the cross product items.

say cross([123], [456], :with(&infix:<*>)).join(",");
# OUTPUT: «4,5,6,8,10,12,12,15,18␤»

The X operator can be combined with another operator as a metaoperator to perform a reduction as well:

say ([123X* [456]).join(",")
# same output as the previous example

routine zip

Defined as:

sub zip(+@e:&with --> Seq:D)

Builds a 'list of lists', returned as a sequence, from multiple input lists or other iterables.

zip iterates through each of the input lists synchronously, 'Zipping' them together, so that elements are grouped according to their input list index, in the order that the lists are provided.

say zip(<a b c>, <d e f>, <g h i>);
# OUTPUT: «((a d g) (b e h) (c f i))␤»

zip has an infix synonym, the Z operator.

say <a b c> Z <d e f> Z <g h i>;                   # same output

zip can provide input to a for loop :

for <a b c> Z <d e f> Z <g h i> -> [$x,$y,$z{say ($x,$y,$z).join(",")}
# OUTPUT: «a,d,g␤b,e,h␤c,f,i␤»

, or more succinctly:

say .join(","for zip <a b c>, <d e f>, <g h i>;  # same output

Note, that if the input lists have an unequal number of elements, then zip terminates once the shortest input list is exhausted, and trailing elements from longer input lists are discarded.

say <a b c> Z <d e f m n o p> Z <g h i>;
# ((a d g) (b e h) (c f i))

In cases where data clipping is possible, but undesired, then consider using roundrobin instead of zip.

The optional with parameter will additionally reduce the zipped lists. For example, the following multiplies corresponding elements together to return a single list of products.

.say for zip <1 2 3>, [123], (123), :with(&infix:<*>);
# OUTPUT: «1␤8␤27␤»

The Z form can also be used to perform reduction by implicitly setting the with parameter with a metaoperator :

.say for <1 2 3> Z* [123Z* (123);        # same output

routine roundrobin

Defined as:

sub roundrobin(+list-of-lists --> Seq)

Builds a 'list of lists', returned as a sequence, from multiple input lists or other iterables. roundrobin returns an identical result to that of zip, except when the input lists are allowed to have an unequal number of elements.

say roundrobin <a b c>, <d e f>, <g h i>;
# OUTPUT: «((a d g) (b e h) (c f i))␤» 
 
say .join(","for roundrobin([12], [23], [34]);
# OUTPUT: «1,2,3␤2,3,4␤»

roundrobin does not terminate once one or more of the input lists become exhausted, but proceeds until all elements from all lists have been processed.

say roundrobin <a b c>, <d e f m n o p>, <g h i j>;
# OUTPUT: «((a d g) (b e h) (c f i) (m j) (n) (o) (p))␤» 
 
say .join(","for roundrobin([12], [235777], [34102]);
# OUTPUT: «1,2,3␤2,3,4␤57,102␤77␤»

Therefore no data values are lost due in the 'zipping' operation. A record of which input list provided which element cannot be gleaned from the resulting sequence, however.

roundrobin can be useful in combining messy data to the point where a manual post-processing step can then be undertaken.

routine sum

Defined as:

sub    sum($list  )
method sum(List:D:)

Returns the sum of all elements in the list or 0 if the list is empty. Throws an exception if an element can not be coerced into Numeric.

say (13pi).sum;       # OUTPUT: «7.14159265358979␤» 
say (1"0xff").sum;      # OUTPUT: «256␤» 
say sum(0b11115);       # OUTPUT: «20␤»

If the list includes a Junction, the result will accordingly be a Junction:

say ( 1|2, 3).sum;            # OUTPUT: «any(4, 5)␤» 

When called on native integer arrays, it is also possible to specify a :wrap named parameter. This will add the values as native integers, wrapping around if they exceed the size of a native integer. If you are sure you will not exceed that value, or if you don't mind, using :wrap will make the calculation about 20x as fast.

my int @values = ^1_000_000;
say @a.sum(:wrap);        # OUTPUT: «499999500000␤» 

method fmt

Defined as:

method fmt($format = '%s'$separator = ' ' --> Str:D)

Returns a string where each element in the list has been formatted according to $format and where each element is separated by $separator.

For more information about formats strings, see sprintf.

my @a = 8..11;
say @a.fmt('%03d'',');  # OUTPUT: «008,009,010,011␤»

method from

Assumes the list contains Match objects and returns the value of .from called on the first element of the list.

'abcdefg' ~~ /(c)(d)/;
say $/.list.from;         # OUTPUT: «2␤» 
 
"abc123def" ~~ m:g/\d/;
say $/.list.from;         # OUTPUT: «3␤»

method to

"abc123def" ~~ m:g/\d/;
say $/.to# OUTPUT: «6␤»

Assumes the List contains Match objects, such as the $/ variable being a List, when using :g modifier in regexes. Returns the value of .to called on the last element of the list.

method sink

Defined as:

method sink(--> Nil{ }

It does nothing, and returns Nil, as the definition clearly shows.

sink [1,2,Failure.new("boo!"),"still here"]; # OUTPUT: «»

method Set

In general, creates a set which has as members elements of the list.

say <æ ß þ €>.Set;  # OUTPUT: «Set(ß æ þ €)␤»

However, there might be some unexpected changes in case the list includes non-scalar data structures. For instance, with Pairs:

my @a = (:42a, :33b);
say @a;                # OUTPUT: «[a => 42 b => 33]␤» 
say @a.Set;            # OUTPUT: «Set(a b)␤»

The set will be composed of the keys of the Pair whose corresponding value is not 0, eliminating all the values. Please check the Set documentation for more examples and a more thorough explanation.

Operators

infix cmp

multi sub infix:<cmp>(List @aList @b)

Evaluates Lists by comparing element @a[$i] with @b[$i] (for some Int $i, beginning at 0) and returning Order::Less, Order::Same, or Order::More depending on if and how the values differ. If the operation evaluates to Order::Same, @a[$i + 1] is compared with @b[$i + 1]. This is repeated until one is greater than the other or all elements are exhausted.

If the Lists are of different lengths, at most only $n comparisons will be made (where $n = @a.elems min @b.elems). If all of those comparisons evaluate to Order::Same, the final value is selected based upon which List is longer.

say (123cmp (123);   # OUTPUT: «Same␤» 
say (456cmp (457);   # OUTPUT: «Less␤» 
say (789cmp (788);   # OUTPUT: «More␤» 
 
say (12)    cmp (123);   # OUTPUT: «Less␤» 
say (123cmp (12);      # OUTPUT: «More␤» 
say (9).List  cmp (^10).List;  # OUTPUT: «More␤»