class Array

Sequence of itemized values
class Array is List {}

An Array is a List which forces all its elements to be scalar containers, which means you can assign to array elements.

Array implements Positional and as such provides support for subscripts.

Note from version 6.d, .raku (.perl before version 2019.11) can be called on multi-dimensional arrays.

If you want to declare an Array of a specific type, you can do so using several different ways:

my @foo of Int = 33,44;        # [33 44]
my @bar is Array[Int] = 33,44; # [33 44]

The second example, which parameterizes a type, is only available from Rakudo 2019.03.

Methods

method gist

Exactly the same as List.gist, except using square brackets for surrounding delimiters.

method pop

method pop(Array:D:) is nodal

Removes and returns the last item from the array. Fails if the array is empty.

Like many Array methods, method pop may be called via the corresponding subroutine. For example:

my @foo = <a b>; # a b
    @foo.pop;        # b
    pop @foo;        # a
    pop @foo;
    CATCH { default { put .^name, ': ', .Str } };
    # OUTPUT: «X::Cannot::Empty: Cannot pop from an empty Array␤»

method push

multi method push(Array:D: **@values is raw --> Array:D)
    multi method push(Array:D: \value --> Array:D)
    multi method push(Array:D: Slip \values --> Array:D)

Adds the provided value or values to the end of the array, and returns the modified array. If any argument is a Slip, method push will add the values produced by the argument's iterator. It throws if the invocant array or a Slip is lazy.

Example:

my @foo = <a b c>;
    @foo.push: 'd';
    say @foo;                   # OUTPUT: «[a b c d]␤»

Note that push does not attempt to flatten its argument list. If you pass an array or list as the thing to push, it becomes one additional element:

my @a = <a b c>;
    my @b = <d e f>;
    @a.push: @b;
    say @a.elems;               # OUTPUT: «4␤»
    say @a[3].join;             # OUTPUT: «def␤»

Multiple values are added to the array only if you supply them as separate arguments or in a Slip:

my @a = '1';
   say @a.push: 'a', 'b';       # OUTPUT: «[1 a b]␤»
   my @c = <E F>;
   say @a.push: @c.Slip;        # OUTPUT: «[1 a b E F]␤»

See method append if you want to append multiple values that are produced by a single non-slipping Iterable.

method append

multi method append(Array:D: **@values is raw --> Array:D)
    multi method append(Array:D: \arg --> Array:D)

Adds the provided values to the end of the array and returns the modified array, or throws if the invocant array or an argument that requires flattening is lazy.

In contrast with method push, method append adheres to the single argument rule and is probably best thought of as:

multi method append(Array:D: +values --> Array:D)

This means that if you pass a single argument that is a non-itemized Iterable, append will try to flatten it.

For example:

my @a = <a b c>;
    my @b = <d e f>;
    @a.append: @b;
    say @a.elems;               # OUTPUT: «6␤»
    say @a;                     # OUTPUT: «[a b c d e f]␤»

method elems

method elems(Array:D: --> Int:D)

Returns the number of elements in the invocant. Throws X::Cannot::Lazy exception if the invocant is lazy. For shaped arrays, returns the outer dimension; see shape if you need information for all dimensions.

say [<foo bar ber>] .elems; # OUTPUT: «3␤»
    say (my @a[42;3;70]).elems; # OUTPUT: «42␤»
try [-∞...∞].elems;
    say $!.^name;               # OUTPUT: «X::Cannot::Lazy␤»

method clone

method clone(Array:D: --> Array:D)

Clones the original Array. Modifications of elements in the clone are not propagated to the original and vice-versa:

my @a = <a b c>; my @b = @a.clone;
    @b[1] = 42; @a.push: 72;
    say @b; # OUTPUT: «[a 42 c]␤»
    say @a; # OUTPUT: «[a b c 72]␤»

However, note that the reifier is shared between the two Arrays, so both Arrays will have the same elements even when each is randomly-generated on reification and each element will be reified just once, regardless of whether the reification was done by the clone or the original Array. Note: just as reifying an Array from multiple threads is not safe, so is, for example, reifying the clone from one thread while reifying the original from another thread is not safe.

my @a = 1, {rand} … ∞; my @b = @a.clone;
    say @b[^3]; # OUTPUT: «(1 0.0216426755282736 0.567660896142156)␤»
    say @a[^3]; # OUTPUT: «(1 0.0216426755282736 0.567660896142156)␤»

method flat

multi method flat(Array:U:)
    multi method flat(Array:D:)

This method will return the type object itself if it's applied to a type object; when applied to an object, it will return a Seq created from the Array underlying iterator.

my @a = <a 2 c>;
say @a.flat.^name; # OUTPUT: «Seq␤»

method shift

method shift(Array:D:) is nodal

Removes and returns the first item from the array. Fails if the array is empty.

Example:

my @foo = <a b>;
    say @foo.shift;             # OUTPUT: «a␤»
    say @foo.shift;             # OUTPUT: «b␤»
    say @foo.shift;
    CATCH { default { put .^name, ': ', .Str } };
    # OUTPUT: «X::Cannot::Empty: Cannot shift from an empty Array␤»

routine unshift

multi        unshift(Array:D, **@values --> Array:D)
    multi method unshift(Array:D: **@values --> Array:D)

Adds the @values to the start of the array, and returns the modified array. Fails if @values is a lazy list.

Example:

my @foo = <a b c>;
    @foo.unshift: 1, 3 ... 11;
    say @foo;                   # OUTPUT: «[(1 3 5 7 9 11) a b c]␤»

The notes in the documentation for method push apply, regarding how many elements are added to the array.

The routine prepend is the equivalent for adding multiple elements from one list or array.

routine prepend

sub prepend(\array, |values)
    multi method prepend(Array:D: \values)
    multi method prepend(Array:D: **@values is raw)

Adds the elements from values to the front of the array, modifying it in-place.

Example:

my @foo = <a b c>;
    @foo.prepend: 1, 3 ... 11;
    say @foo;                   # OUTPUT: «[1 3 5 7 9 11 a b c]␤»

The difference from method unshift is that if you prepend a single array or list argument, prepend will flatten that array / list, whereas unshift prepends the list / array as just a single element.

routine splice

multi        splice(@list,   $start = 0, $elems?, *@replacement --> Array)
    multi method splice(Array:D: $start = 0, $elems?, *@replacement --> Array)

Deletes $elems elements starting from index $start from the Array, returns them and replaces them by @replacement. If $elems is omitted or is larger than the number of elements starting from $start, all the elements starting from index $start are deleted. If both $start and $elems are omitted, all elements are deleted from the Array and returned.

Each of $start and $elems can be specified as a Whatever or as a Callable that returns an Int-compatible value: this returned value is then used as the corresponding argument to the splice routine.

A Whatever $start uses the number of elements of @list (or invocant). A Callable $start is called with one argument—the number of elements in @list (or self).

A Whatever $elems deletes from $start to end of @list (or self) (same as no $elems). A Callable $elems is called with one argument—the number of elements in @list (or self) minus the value of $start.

Example:

my @foo = <a b c d e f g>;
    say @foo.splice(2, 3, <M N O P>);        # OUTPUT: «[c d e]␤»
    say @foo;                                # OUTPUT: «[a b M N O P f g]␤»

It can be used to extend an array by simply splicing in more elements than the current size (since version 6.d)

my @foo = <a b c d e f g>;
say @foo.splice(6, 4, <M N O P>);       # OUTPUT: «[g]␤»
say @foo;                               # OUTPUT: «[a b c d e f M N O P]␤»

The following equivalences hold (assuming that @a.elems ≥ $i):

@a.push($x, $y)      @a.splice: *  , *, $x, $y
@a.pop               @a.splice: *-1,
@a.shift             @a.splice: 0  , 1,
@a.unshift($x, $y)   @a.splice: 0  , 0, $x, $y
@a[$i] = $y          @a.splice: $i , 1, $y,

As mentioned above, a Whatever or Callable object can be provided for both the $start and $elems parameters. For example, we could use either of them to remove the second to last element from an array provided it's large enough to have one:

my @foo = <a b c d e f g>;
    say @foo.splice: *-2, *-1;           # OUTPUT: «[f]␤»
    say @foo;                            # OUTPUT: «[a b c d e g]␤»
my &start     = -> $n { $n - 2 };
    my &elems-num = -> $m { $m - 1 };
    say @foo.splice: &start, &elems-num; # OUTPUT: «[e]␤»
    say @foo;                            # OUTPUT: «[a b c d g]␤»

method shape

method shape() { (*,) }

Returns the shape of the array as a list.

Example:

my @foo[2;3] = ( < 1 2 3 >, < 4 5 6 > ); # Array with fixed dimensions
    say @foo.shape;                          # OUTPUT: «(2 3)␤»
    my @bar = ( < 1 2 3 >, < 4 5 6 > );      # Normal array (of arrays)
    say @bar.shape;                          # OUTPUT: «(*)␤»

method default

method default

Returns the default value of the invocant, i.e. the value which is returned when trying to access an element in the Array which has not been previously initialized or when accessing an element which has explicitly been set to Nil. Unless the Array is declared as having a default value by using the is default trait the method returns the type object for Any.

my @a1 = 1, "two", 2.718;
say @a1.default;                               # OUTPUT: «(Any)␤»
say @a1[4];                                    # OUTPUT: «(Any)␤»

my @a2 is default(17) = 1, "two", 3;
say @a2.default;                               # OUTPUT: «17␤»
say @a2[4];                                    # OUTPUT: «17␤»
@a2[1] = Nil;                                  # (resets element to its default)
say @a2[1];                                    # OUTPUT: «17␤»

method of

method of()

Returns the type constraint for the values of the invocant. By default, i.e. if no type constraint is given during declaration, the method returns (Mu).

my @a1 = 1, 'two', 3.14159;              # (no type constraint specified)
    say @a1.of;                              # OUTPUT: «(Mu)␤»
my Int @a2 = 1, 2, 3;                    # (values must be of type Int)
    say @a2.of;                              # OUTPUT: «(Int)␤»
    @a2.push: 'd';
    CATCH { default { put .^name, ': ', .Str } };
    # OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to @a2; expected Int but got Str ("d")␤»

method dynamic

method dynamic(Array:D: --> Bool:D)

Returns True if the invocant has been declared with the is dynamic trait, that is, if it's a dynamic variable that can be accessed from the inner lexical scope without having been declared there.

my @a;
    say @a.dynamic;                          # OUTPUT: «False␤»
my @b is dynamic;
    say @b.dynamic;                          # OUTPUT: «True␤»

If you declare a variable with the * twigil is dynamic is implied.

my @*b;
    say @*b.dynamic;                         # OUTPUT: «True␤»

Please note that the dynamic trait is a property of the variable, not the content. If a Scalar dynamic variable contains an array, rules for this container will apply (and it will always return False).

method List

multi method List(Array:D:)

Converts the array to a List.

my @array= [1];
@array[3]=3;
say @array.List;       # OUTPUT: «(1 Nil Nil 3)␤»

The holes will show up as Nil.

method Slip

multi method Slip(Array:D: --> Slip:D)

Converts the array to a Slip, filling the holes with the type value the Array has been defined with.

my Int @array= [0];
@array[3]=3;
say @array.Slip; # OUTPUT: «(0 (Int) (Int) 3)␤»

See Also

class Bag

Immutable collection of distinct objects with integer weights

class BagHash

Mutable collection of distinct objects with integer weights

class Capture

Argument list suitable for passing to a Signature

class Hash

Mapping from strings to itemized values

class IterationBuffer

Low level storage of positional values

class List

Sequence of values

class Map

Immutable mapping from strings to values

class Mix

Immutable collection of distinct objects with Real weights

class MixHash

Mutable collection of distinct objects with Real weights

class NFC

Codepoint string in Normal Form C (composed)

class NFD

Codepoint string in Normal Form D (decomposed)

class NFKC

Codepoint string in Normal Form KC (compatibility composed)

class NFKD

Codepoint string in Normal Form KD (compatibility decomposed)

class Pair

Key/value pair

class PseudoStash

Stash type for pseudo-packages

class Range

Interval of ordered values

class Seq

An iterable, potentially lazy sequence of values

class Set

Immutable collection of distinct objects

class SetHash

Mutable collection of distinct objects

class Slip

A kind of List that automatically flattens into an outer container

class Stash

Table for "our"-scoped symbols

class Uni

A string of Unicode codepoints

class utf8

Mutable uint8 buffer for utf8 binary data

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.