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 |  
  |  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 |  
  |  concatenates the first array with the second | 
== operator |  
  |  are two arrays the same (elements compared with the == operator, if defined)? |  
!= operator |  
  |  are two arrays different (elements compared with the == operator, if defined)? |  
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 |  
  |  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 |  
  |  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 |  
  |  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: 
  |  
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):
  |  
drain |  
  |  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):
  |  
retain |  
  |  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 |  
  |  replaces a portion of the array with another (not necessarily of the same length as the replaced portion) | 
splice |  
  |  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):
  |  
contains, in operator |  element to find | does the array contain an element? The == operator is used for comparison |  
index_of |  
  |  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 |  
  |  returns the position of the first element in the array that returns true when called with the predicate function, or −1 if not found:
  |  
find |  
  |  returns the first element in the array that returns true when called with the predicate function, or () if not found:
  |  
find_map |  
  |  returns the first non-() value of the first element in the array when called with the predicate function, or () if not found:
  |  
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):
  |  
reduce |  
  |  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):
  |  
reduce_rev |  
  |  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):
  |  
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):
  |  
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):
  |  
sort |  function pointer to a comparison function (usually a closure) | sorts the array with a comparison function taking the following parameters:
  |  
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 == []