Primitive array
Implementations
impl<T, #uint N> [T; N]
fn all(self, f: impl Fn(T) -> bool) -> bool
Returns whether the provided predicate is true for all array elements.
Note that an empty array has no elements, so the result will always be true regardless of
the predicate.
Examples
assert [].any(fn |x| x == 0u8) == false;
assert [7u8, 10u8, 13u8].all(fn |x| x > 5) == true;
assert [7u8, 10u8, 13u8].all(fn |x| x > 12) == false;
assert [7u8, 10u8, 13u8].all(fn |x| x > 20) == false;fn any(self, f: impl Fn(T) -> bool) -> bool
Returns whether the provided predicate is true for at least one array element.
Note that an empty array has no elements, so the result will always be false regardless of
the predicate.
Examples
assert [].any(fn |x| x == 0u8) == false;
assert [7u8, 10u8, 13u8].any(fn |x| x > 5) == true;
assert [7u8, 10u8, 13u8].any(fn |x| x > 12) == true;
assert [7u8, 10u8, 13u8].any(fn |x| x > 20) == false;fn chunks<#uint ChunkSize>(self) -> [[T; ChunkSize]; { N / ChunkSize }]
where
N == N / ChunkSize * ChunkSize else "The size of the input array must be a multiple of the chunk size",
Splits the array into equally-sized chunks.
The chunk size is provided at compile time as a type parameter. This means that it cannot depend on a runtime value. However, it also means that it can be inferred.
Examples
let array = [1u8, 2u8, 3u8, 4u8, 5u8, 6u8];
let two_item_chunks = array.chunks::<2>();
assert two_item_chunks[0] == [1u8, 2u8];
assert two_item_chunks[1] == [3u8, 4u8];
assert two_item_chunks[2] == [5u8, 6u8];
let three_item_chunks = array.chunks::<3>();
assert three_item_chunks[0] == [1u8, 2u8, 3u8];
assert three_item_chunks[1] == [4u8, 5u8, 6u8];pub fn concat<#uint M>(self, other: [T; M]) -> [T; { M + N }]
Creates an array by concatenating the elements of two existing ones.
The result is an array whose lower elements correspond to the first input array, and its
higher elements correspond to the second one. In other words, given two arrays
[l0, l1, ...] and [r0, r1, ...], the result is [l0, l1, ..., r0, r1, ...].
Examples
let empty: [uint<8>; 0] = [];
assert [].concat([]) == empty;
assert [1u8].concat([2u8, 3u8]) == [1u8, 2u8, 3u8];fn reversed(self) -> Self
Reverses the elements of an array.
Examples
let empty: [uint<8>; 0] = [];
assert [].reversed() == empty;
assert [1u8, 2u8, 3u8].reversed() == [3u8, 2u8, 1u8];fn fold<B>(self, init: B, f: impl Fn(B, T) -> B) -> B
Folds an array into a single value using a function to assimilate elements.
Given an input array [a0, a1, a2, ...] and a function f, the output would be
f(init f(a0, f(a1, f(a2, ...)))).
As opposed to reduce, this function requires an initial value for the accumulator. This
allows the accumulator and the array elements to have a different type, and the method to
operate on empty arrays.
See also [T; N]::fold.
Examples
assert [1u8, 2u8, 3u8, 4u8].fold(0, fn |acc, val| acc +. val) == 10u8;
assert [1u8, 2u8, 3u8, 4u8].fold(true, fn |acc, val| acc && val != 4) == false;fn interleave(self, other: Self) -> [T; { 2 * N }]
Interleaves the elements of two arrays.
An array containing elements from both input arrays is built, with even positions occupied
by elements from the first array and odd positions occupied by those from the second array.
In other words, given two arrays [l0, l1, l2, ...] and [r0, r1, r2, ...], the output
would be [l0, r0, l1, r1, l2, r2, ...].
Examples
let l = [10u8, 11u8, 12u8];
let r = [20u8, 21u8, 22u8];
assert l.interleave(r) == [10u8, 20u8, 11u8, 21u8, 12u8, 22u8];
let empty: [uint<8>; 0] = [];
assert [].interleave([]) == empty;fn map<O>(self, f: impl Fn(T) -> O) -> [O; N]
Builds an array by applying a function to each element of the input array.
Examples
let array = [1u8, 2u8, 3u8, 4u8];
assert array.map(fn |x| x < 4) == [true, true, true, false];pub fn push_back(self, item: T) -> [T; { N + 1 }]
Creates a new array with item added at the end of the original array
Examples
let a = [];
let b = a.push_back(1u8);
let c = b.push_back(2u8);
let d = c.push_back(3u8);
assert b == [1u8];
assert c == [1u8, 2u8];
assert d == [1u8, 2u8, 3u8];pub fn push_front(self, item: T) -> [T; { N + 1 }]
Adds an element at the start of the array.
Examples
let a = [];
let b = a.push_front(1u8);
let c = b.push_front(2u8);
let d = c.push_front(3u8);
assert b == [1u8];
assert c == [2u8, 1u8];
assert d == [3u8, 2u8, 1u8];fn sliding_window<#uint M>(self) -> [[T; M]; { N - M + 1 }]
where
M <= N else "Window size is larger than array size",
Generates an array with the intermediate values of an sliding window over the input array.
The window size is provided at compile time as a type parameter. This means that it cannot depend on a runtime value. However, it also means that it can be inferred.
Examples
let array = [1u8, 2u8, 3u8, 4u8, 5u8];
let two_item_windows = array.sliding_window::<2>();
assert two_item_windows[0] == [1u8, 2u8];
assert two_item_windows[1] == [2u8, 3u8];
assert two_item_windows[2] == [3u8, 4u8];
assert two_item_windows[3] == [4u8, 5u8];
let three_item_windows = array.sliding_window::<3>();
assert three_item_windows[0] == [1u8, 2u8, 3u8];
assert three_item_windows[1] == [2u8, 3u8, 4u8];
assert three_item_windows[2] == [3u8, 4u8, 5u8];fn split_at<#uint K>(self) -> ([T; K], [T; { N - K }])
where
K <= N else "Split point is outside array bounds",
Splits an array into two parts.
The split point is provided at compile time as a type parameter. This means that it cannot depend on a runtime value. However, it also means that it can be inferred.
Examples
let empty: [uint<8>; 0] = [];
assert empty.split_at::<0>() == ([], []);
assert [1u8, 2u8, 3u8].split_at::<0>() == ([], [1u8, 2u8, 3u8]);
assert [1u8, 2u8, 3u8].split_at::<1>() == ([1u8], [2u8, 3u8]);
assert [1u8, 2u8, 3u8].split_at::<2>() == ([1u8, 2u8], [3u8]);
assert [1u8, 2u8, 3u8].split_at::<3>() == ([1u8, 2u8, 3u8], []);
assert [1u8, 2u8, 3u8].split_at() == ([1u8, 2u8], [3u8]);
assert [1u8, 2u8, 3u8].split_at() == ([1u8, 2u8, 3u8], []);fn zip<O>(self, other: [O; N]) -> [(T, O); N]
Pairs elements of two arrays together into a single array of tuples.
An array is produced with the same length as both inputs provided. For each array position,
the elements from both arrays are paired as a tuple and stored in the result array. In other
words, given two arrays [l0, l1, l2, ...] and [r0, r1, r2, ...], the output would be
[(l0, r0), (l1, r1), (l2, r2), ...].
Examples
let l = [10u8, 11u8, 12u8];
let r = [20u8, 21u8, 22u8];
assert l.zip(r) == [(10u8, 20u8), (11u8, 21u8), (12u8, 22u8)];
let empty: [(uint<8>, uint<8>); 0] = [];
assert [].zip([]) == empty;fn len(self) -> uint<{ }>
Returns the length of the array.
Since arrays are static, this simply returns a constant value.
let empty: [uint<8>; 0] = [];
assert empty.len() == 0;
assert [true].len() == 1;
assert [true, false].len() == 2;impl<T, #uint N> [T; N]
where
N > 0,
pub fn first(self) -> T
Retrieves the first element of the array.
Examples
assert [true].first() == true;
assert [true, false].first() == true;pub fn last(self) -> T
Retrieves the last element of the array.
Examples
assert [true].last() == true;
assert [true, false].last() == false;fn reduce(self, f: impl Fn(T, T) -> T) -> T
Reduces an array to a single value using a function to assimilate elements.
Given an input array [a0, a1, a2, ...] and a function f, the output would be
f(a0, f(a1, f(a2, ...))).
As opposed to fold, this function operates without an initial value for the accumulator by
taking the first element of the array instead. This requires the accumulator and the array
elements to have the same type, and the array to not be empty.
See also [T; N]::fold.
Examples
assert [1u8, 2u8, 3u8, 4u8].reduce(fn |a, b| a +. b) == 10u8;pub fn shift_back(self, item: T) -> Self
Shifts an element into the end of the array, dropping the first one.
Examples
let a = [1u8, 2u8, 3u8];
let b = a.shift_back(4u8);
let c = b.shift_back(5u8);
let d = c.shift_back(6u8);
assert b == [2u8, 3u8, 4u8];
assert c == [3u8, 4u8, 5u8];
assert d == [4u8, 5u8, 6u8];pub fn shift_front(self, item: T) -> Self
Shifts an element into the start of the array, dropping the last one.
Examples
let a = [3u8, 2u8, 1u8];
let b = a.shift_front(4u8);
let c = b.shift_front(5u8);
let d = c.shift_front(6u8);
assert b == [4u8, 3u8, 2u8];
assert c == [5u8, 4u8, 3u8];
assert d == [6u8, 5u8, 4u8];impl<T, #uint N> inv [T; N]
fn transpose(self) -> [inv T; N]
Transposes an inv array into an array of inv values.
This transformation preserves the low level signals behind the value, but presents them in a new format that is easier to destructure.
Examples
let a = port();
let inv_array: inv [bool; 2] = a.1;
let array_of_invs: [inv bool; 2] = inv_array.transpose();
set array_of_invs[0] = true;
set array_of_invs[1] = false;
assert a.0 == [true, false];impl<T, #uint N, #uint M> [[T; M]; N]
fn flatten(self) -> [T; { N * M }]
Turns an array of arrays into a single array containing the same elements in the same order.
This operation only flattens one level of nesting, requiring multiple calls to flatten a deeply-nested array value.
Examples
let empty: [[uint<8>; 0]; 0] = [];
assert empty.flatten() == [];
assert [[1u8], [2u8], [3u8], [4u8]].flatten() == [1u8, 2u8, 3u8, 4u8];
assert [[[1u8], [2u8]], [[3u8], [4u8]]].flatten() == [[1u8], [2u8], [3u8], [4u8]];