Arrays

Arrays are first-class citizens in Rhai.

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

[ value , value , ... , value ]

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

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

The Rust type of a Rhai array is rhai::Array.

type_of() an array returns "array".

Arrays are disabled via the no_index feature.

The maximum allowed size of an array can be controlled via Engine::set_max_array_size (see maximum size of arrays.

Element Access

From beginning

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

array [ index from 0 to (length−1) ]

From end

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

array [ index from −1 to −length ]

Built-in Functions

The following methods (mostly defined in the BasicArrayPackage but excluded if using a raw Engine) operate on arrays:

FunctionParameter(s)Description
pushelement to insertinserts an element at the end
appendarray to appendconcatenates the second array to the end of the first
+= operator1) array
2) element to insert (not another array)
inserts an element at the end
+= operator1) array
2) array to append
concatenates the second array to the end of the first
+ operator1) first array
2) second array
concatenates the first array with the second
== operator1) first array
2) second array
are the two arrays the same (elements compared with the == operator, if defined)?
!= operator1) first array
2) second array
are the two arrays different (elements compared with the == operator, if defined)?
insert1) position, counting from end if < 0, end if ≥ length
2) element to insert
inserts an element at a certain index
popnoneremoves the last element and returns it (() if empty)
shiftnoneremoves the first element and returns it (() if empty)
extract1) start position, counting from end if < 0, end if ≥ length
2) (optional) number of items to extract, none if < 0
extracts a portion of the array into a new array
removeindexremoves an element at a particular index and returns it (() if the index is not valid)
reversenonereverses the array
len method and propertynonereturns the number of elements
pad1) 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
split1) 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
drain1) function pointer to predicate (usually a closure)removes all items (returning them) that return true when called with the predicate function:
1st parameter: array item
2nd parameter: (optional) offset index
drain1) start position, counting from end if < 0, end if ≥ length
2) number of items to remove, none if < 0
removes a portion of the array, returning the removed items (not in original order)
retain1) function pointer to predicate (usually a closure)removes all items (returning them) that do not return true when called with the predicate function:
1st parameter: array item
2nd parameter: (optional) offset index
retain1) start position, counting from end if < 0, end if ≥ length
2) number of items to retain, none if < 0
retains a portion of the array, removes all other items and returning them (not in original order)
splice1) start position, counting from end if < 0, end if ≥ length
2) number of items 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)
filterfunction pointer to predicate (usually a closure)constructs a new array with all items that return true when called with the predicate function:
1st parameter: array item
2nd parameter: (optional) offset index
containselement to finddoes the array contain an element? The == operator (if defined) is used to compare custom types
index_of1) element to find (not a function pointers)
2) (optional) start index, counting from end if < 0, end if ≥ length
returns the index of the first item in the array that equals the supplied element (using the == operator, if defined), or −1 if not found
index_of1) function pointer to predicate (usually a closure)
2) (optional) start index, counting from end if < 0, end if ≥ length
returns the index of the first item in the array that returns true when called with the predicate function, or −1 if not found:
1st parameter: array item
2nd parameter: (optional) offset index
mapfunction pointer to conversion function (usually a closure)constructs a new array with all items mapped to the result of applying the conversion function:
1st parameter: array item
2nd parameter: (optional) offset index
reduce1) function pointer to accumulator function (usually a closure)
2) (optional) the initial value
reduces the array into a single value via the accumulator function:
1st parameter: accumulated value (() initially)
2nd parameter: array item
3rd parameter: (optional) offset index
reduce_rev1) 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:
1st parameter: accumulated value (() initially)
2nd parameter: array item
3rd parameter: (optional) offset index
somefunction pointer to predicate (usually a closure)returns true if any item returns true when called with the predicate function:
1st parameter: array item
2nd parameter: (optional) offset index
allfunction pointer to predicate (usually a closure)returns true if all items return true when called with the predicate function:
1st parameter: array item
2nd parameter: (optional) offset index
sortfunction pointer to a comparison function (usually a closure)sorts the array with a comparison function:
1st parameter: first item
2nd parameter: second item
return value: INT < 0 if first < second, > 0 if first > second, 0 if first == second

Use Custom Types With Arrays

To use a custom type with arrays, a number of array functions need to be manually implemented, in particular the == operator in order to support the in operator which uses == (via the contains method) to compare elements.

See the section on custom types for more details.

Examples


#![allow(unused)]
fn main() {
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 item 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 item 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 index 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 item in y {             // arrays can be iterated with a 'for' statement
    print(item);
}

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;

let a = [42, 123, 99];

a.map(|v| v + 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(|v, i| i == 1);    // returns [123]

// Provide an initial value directly
a.reduce(|sum, v| sum + v, 0) == 264;

// Detect the initial value of '()'
a.reduce(
    |sum, v| if sum.type_of() == "()" { v } else { sum + v }
) == 264;

// Detect the initial value via index
a.reduce(|sum, v, i|
    if i == 0 { v } else { sum + v }
) == 264;

// Provide an initial value directly
a.reduce_rev(|sum, v| sum + v, 0) == 264;

// Detect the initial value of '()'
a.reduce_rev(
    |sum, v| if sum.type_of() == "()" { v } else { sum + v }
) == 264;

// Detect the initial value via index
a.reduce_rev(|sum, v, i|
    if i == 2 { v } else { sum + v }
) == 264;

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

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

a.none(|v| v != 0);         // returns false

a.none(|v, i| v == i);      // returns true

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

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

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| x - y);       // 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 == []
}