Arrays

Arrays are first-class citizens in Rhai.

All elements stored in an array are dynamic, and the array can freely grow or shrink with elements added or removed.

type_of() an array returns "array".

Literal Syntax

Array literals are built within square brackets [] and separated by commas ,:

[ value, value,, value ]

[ value, value,, value , ] // trailing comma is OK

Element Access Syntax

From beginning

Like C, arrays are accessed with zero-based, non-negative integer indices:

array [ index position from 0 to length−1 ]

From end

A negative position accesses an element in the array counting from the end, with −1 being the last element.

array [ index position from −1 to −length ]

Built-in Functions

The following methods operate on arrays.

FunctionParameter(s)Description
getposition, counting from end if < 0gets a copy of the element at a certain position (() if the position is not valid)
set
  1. position, counting from end if < 0
  2. new element
sets a certain position to a new value (no effect if the position is not valid)
push, += operatorelement to append (not an array)appends an element to the end
append, += operatorarray to appendconcatenates the second array to the end of the first
+ operator
  1. first array
  2. second array
concatenates the first array with the second
== operator
  1. first array
  2. second array
are two arrays the same (elements compared with the == operator, if defined)?
!= operator
  1. first array
  2. second array
are two arrays different (elements compared with the == operator, if defined)?
insert
  1. position, counting from end if < 0, end if ≥ length
  2. element to insert
inserts an element at a certain position
popnoneremoves the last element and returns it (() if empty)
shiftnoneremoves the first element and returns it (() if empty)
extract
  1. start position, counting from end if < 0, end if ≥ length
  2. (optional) number of elements to extract, none if ≤ 0, to end if omitted
extracts a portion of the array into a new array
extractrange of elements to extract, from beginning if ≤ 0, to end if ≥ lengthextracts a portion of the array into a new array
removeposition, counting from end if < 0removes an element at a particular position and returns it (() if the position is not valid)
reversenonereverses the array
len method and propertynonereturns the number of elements
is_empty method and propertynonereturns true if the array is empty
pad
  1. target length
  2. element to pad
pads the array with an element to at least a specified length
clearnoneempties the array
truncatetarget lengthcuts off the array at exactly a specified length (discarding all subsequent elements)
choptarget lengthcuts off the head of the array, leaving the tail at exactly a specified length
split
  1. array
  2. position to split at, counting from end if < 0, end if ≥ length
splits the array into two arrays, starting from a specified position
for_eachfunction pointer for processing elementsrun through each element in the array in order, binding each to this and calling the processing function taking the following parameters:
  1. this: array element
  2. (optional) index position
drainfunction pointer to predicate (usually a closure)removes all elements (returning them) that return true when called with the predicate function taking the following parameters (if none, the array element is bound to this):
  1. array element
  2. (optional) index position
drain
  1. start position, counting from end if < 0, end if ≥ length
  2. number of elements to remove, none if ≤ 0
removes a portion of the array, returning the removed elements as a new array
drainrange of elements to remove, from beginning if ≤ 0, to end if ≥ lengthremoves a portion of the array, returning the removed elements as a new array
retainfunction pointer to predicate (usually a closure)removes all elements (returning them) that do not return true when called with the predicate function taking the following parameters (if none, the array element is bound to this):
  1. array element
  2. (optional) index position
retain
  1. start position, counting from end if < 0, end if ≥ length
  2. number of elements to retain, none if ≤ 0
retains a portion of the array, removes all other elements and returning them as a new array
retainrange of elements to retain, from beginning if ≤ 0, to end if ≥ lengthretains a portion of the array, removes all other bytes and returning them as a new array
splice
  1. start position, counting from end if < 0, end if ≥ length
  2. number of elements to remove, none if ≤ 0
  3. array to insert
replaces a portion of the array with another (not necessarily of the same length as the replaced portion)
splice
  1. range of elements to remove, from beginning if ≤ 0, to end if ≥ length
  2. array to insert
replaces a portion of the array with another (not necessarily of the same length as the replaced portion)
filterfunction pointer to predicate (usually a closure)constructs a new array with all elements that return true when called with the predicate function taking the following parameters (if none, the array element is bound to this):
  1. array element
  2. (optional) index position
contains, in operatorelement to finddoes the array contain an element? The == operator is used for comparison
index_of
  1. element to find (not a function pointer)
  2. (optional) start position, counting from end if < 0, end if ≥ length
returns the position of the first element in the array that equals the supplied element (using the == operator, if defined), or −1 if not found
index_of
  1. function pointer to predicate (usually a closure)
  2. (optional) start position, counting from end if < 0, end if ≥ length
returns the position of the first element in the array that returns true when called with the predicate function, or −1 if not found:
  1. this: array element
  2. (optional) index position
find
  1. function pointer to predicate (usually a closure)
  2. (optional) start position, counting from end if < 0, end if ≥ length
returns the first element in the array that returns true when called with the predicate function, or () if not found:
  1. array element (if none, the array element is bound to this)
  2. (optional) index position
find_map
  1. function pointer to predicate (usually a closure)
  2. (optional) start position, counting from end if < 0, end if ≥ length
returns the first non-() value of the first element in the array when called with the predicate function, or () if not found:
  1. array element (if none, the array element is bound to this)
  2. (optional) index position
dedup(optional) function pointer to predicate (usually a closure); if omitted, the == operator is used, if definedremoves all but the first of consecutive elements in the array that return true when called with the predicate function (non-consecutive duplicates are not removed):
1st & 2nd parameters: two elements in the array
mapfunction pointer to conversion function (usually a closure)constructs a new array with all elements mapped to the result of applying the conversion function taking the following parameters (if none, the array element is bound to this):
  1. array element
  2. (optional) index position
reduce
  1. function pointer to accumulator function (usually a closure)
  2. (optional) the initial value
reduces the array into a single value via the accumulator function taking the following parameters (if the second parameter is omitted, the array element is bound to this):
  1. accumulated value (() initially)
  2. array element
  3. (optional) index position
reduce_rev
  1. function pointer to accumulator function (usually a closure)
  2. (optional) the initial value
reduces the array (in reverse order) into a single value via the accumulator function taking the following parameters (if the second parameter is omitted, the array element is bound to this):
  1. accumulated value (() initially)
  2. array element
  3. (optional) index position
somefunction pointer to predicate (usually a closure)returns true if any element returns true when called with the predicate function taking the following parameters (if none, the array element is bound to this):
  1. array element
  2. (optional) index position
allfunction pointer to predicate (usually a closure)returns true if all elements return true when called with the predicate function taking the following parameters (if none, the array element is bound to this):
  1. array element
  2. (optional) index position
sortfunction pointer to a comparison function (usually a closure)sorts the array with a comparison function taking the following parameters:
  1. first element
  2. second element
    return value: INT < 0 if first < second, > 0 if first > second, 0 if first == second
sortnonesorts a homogeneous array containing only elements of the same comparable built-in type (integers, floating-point, decimal, string, character, bool, ())

Examples

let y = [2, 3];             // y == [2, 3]

let y = [2, 3,];            // y == [2, 3]

y.insert(0, 1);             // y == [1, 2, 3]

y.insert(999, 4);           // y == [1, 2, 3, 4]

y.len == 4;

y[0] == 1;
y[1] == 2;
y[2] == 3;
y[3] == 4;

(1 in y) == true;           // use 'in' to test if an element exists in the array

(42 in y) == false;         // 'in' uses the 'contains' function, which uses the
                            // '==' operator (that users can override)
                            // to check if the target element exists in the array

y.contains(1) == true;      // the above de-sugars to this

y[1] = 42;                  // y == [1, 42, 3, 4]

(42 in y) == true;

y.remove(2) == 3;           // y == [1, 42, 4]

y.len == 3;

y[2] == 4;                  // elements after the removed element are shifted

ts.list = y;                // arrays can be assigned completely (by value copy)

ts.list[1] == 42;

[1, 2, 3][0] == 1;          // indexing on array literal

[1, 2, 3][-1] == 3;         // negative position counts from the end

fn abc() {
    [42, 43, 44]            // a function returning an array
}

abc()[0] == 42;

y.push(4);                  // y == [1, 42, 4, 4]

y += 5;                     // y == [1, 42, 4, 4, 5]

y.len == 5;

y.shift() == 1;             // y == [42, 4, 4, 5]

y.chop(3);                  // y == [4, 4, 5]

y.len == 3;

y.pop() == 5;               // y == [4, 4]

y.len == 2;

for element in y {          // arrays can be iterated with a 'for' statement
    print(element);
}

y.pad(6, "hello");          // y == [4, 4, "hello", "hello", "hello", "hello"]

y.len == 6;

y.truncate(4);              // y == [4, 4, "hello", "hello"]

y.len == 4;

y.clear();                  // y == []

y.len == 0;

// The examples below use 'a' as the master array

let a = [42, 123, 99];

a.map(|v| v + 1);           // returns [43, 124, 100]

a.map(|| this + 1);         // returns [43, 124, 100]

a.map(|v, i| v + i);        // returns [42, 124, 101]

a.filter(|v| v > 50);       // returns [123, 99]

a.filter(|| this > 50);     // returns [123, 99]

a.filter(|v, i| i == 1);    // returns [123]

a.filter("is_odd");         // returns [123, 99]

a.filter(Fn("is_odd"));     // <- previous statement is equivalent to this...

a.filter(|v| is_odd(v));    // <- or this

a.some(|v| v > 50);         // returns true

a.some(|| this > 50);       // returns true

a.some(|v, i| v < i);       // returns false

a.all(|v| v > 50);          // returns false

a.all(|| this > 50);        // returns false

a.all(|v, i| v > i);        // returns true

// Reducing - initial value provided directly
a.reduce(|sum| sum + this, 0) == 264;

// Reducing - initial value provided directly
a.reduce(|sum, v| sum + v, 0) == 264;

// Reducing - initial value is '()'
a.reduce(
    |sum, v| if sum.type_of() == "()" { v } else { sum + v }
) == 264;

// Reducing - initial value has index position == 0
a.reduce(|sum, v, i|
    if i == 0 { v } else { sum + v }
) == 264;

// Reducing in reverse - initial value provided directly
a.reduce_rev(|sum| sum + this, 0) == 264;

// Reducing in reverse - initial value provided directly
a.reduce_rev(|sum, v| sum + v, 0) == 264;

// Reducing in reverse - initial value is '()'
a.reduce_rev(
    |sum, v| if sum.type_of() == "()" { v } else { sum + v }
) == 264;

// Reducing in reverse - initial value has index position == 0
a.reduce_rev(|sum, v, i|
    if i == 2 { v } else { sum + v }
) == 264;

// In-place modification

a.splice(1..=1, [1, 3, 2]); // a == [42, 1, 3, 2, 99]

a.extract(1..=3);           // returns [1, 3, 2]

a.sort(|x, y| y - x);       // a == [99, 42, 3, 2, 1]

a.sort();                   // a == [1, 2, 3, 42, 99]

a.drain(|v| v <= 1);        // a == [2, 3, 42, 99]

a.drain(|v, i| i ≥ 3);      // a == [2, 3, 42]

a.retain(|v| v > 10);       // a == [42]

a.retain(|v, i| i > 0);     // a == []