Skip to content

Arrays

Arrays are first-class citizens in AviScript.

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.

Function Parameter(s) Description
get position, counting from end if < 0 gets 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, += operator element to append (not an array) appends an element to the end
append, += operator array to append concatenates 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
pop none removes the last element and returns it (() if empty)
shift none removes 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
extract range of elements to extract, from beginning if ≤ 0, to end if ≥ length extracts a portion of the array into a new array
remove position, counting from end if < 0 removes an element at a particular position and returns it (() if the position is not valid)
reverse none reverses the array
len method and property none returns the number of elements
is_empty method and property none returns 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
clear none empties the array
truncate target length cuts off the array at exactly a specified length (discarding all subsequent elements)
chop target length cuts 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_each function pointer for processing elements run 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
drain function 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
drain range of elements to remove, from beginning if ≤ 0, to end if ≥ length removes a portion of the array, returning the removed elements as a new array
retain function 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
retain range of elements to retain, from beginning if ≤ 0, to end if ≥ length retains 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)
filter function 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 operator element to find does 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 defined removes 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
map function 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
some function 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
all function 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
sort function 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
sort none sorts 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 == []