Skip to main content

Array

Provides extended utility functions on Arrays.

Note the difference between mutable and non-mutable arrays below.

WARNING: If you are looking for a list that can grow and shrink in size, it is recommended you use either the Buffer class or the List class for those purposes. Arrays must be created with a fixed size.

Import from the base library to use this module.

import Array "mo:base/Array";

Function init

func init<X>(size : Nat, initValue : X) : [var X]

Create a mutable array with size copies of the initial value.

let array = Array.init<Nat>(4, 2);

Runtime: O(size) Space: O(size)

Function tabulate

func tabulate<X>(size : Nat, generator : Nat -> X) : [X]

Create an immutable array of size size. Each element at index i is created by applying generator to i.

let array : [Nat] = Array.tabulate<Nat>(4, func i = i * 2);

Runtime: O(size) Space: O(size)

*Runtime and space assumes that generator runs in O(1) time and space.

Function tabulateVar

func tabulateVar<X>(size : Nat, generator : Nat -> X) : [var X]

Create a mutable array of size size. Each element at index i is created by applying generator to i.

let array : [var Nat] = Array.tabulateVar<Nat>(4, func i = i * 2);
array[2] := 0;
array

Runtime: O(size) Space: O(size)

*Runtime and space assumes that generator runs in O(1) time and space.

Function freeze

func freeze<X>(varArray : [var X]) : [X]

Transforms a mutable array into an immutable array.


let varArray = [var 0, 1, 2];
varArray[2] := 3;
let array = Array.freeze<Nat>(varArray);

Runtime: O(size)

Space: O(1)

Function thaw

func thaw<A>(array : [A]) : [var A]

Transforms an immutable array into a mutable array.


let array = [0, 1, 2];
let varArray = Array.thaw<Nat>(array);
varArray[2] := 3;
varArray

Runtime: O(size)

Space: O(1)

Function equal

func equal<X>(array1 : [X], array2 : [X], equal : (X, X) -> Bool) : Bool

Tests if two arrays contain equal values (i.e. they represent the same list of elements). Uses equal to compare elements in the arrays.

// Use the equal function from the Nat module to compare Nats
import {equal} "mo:base/Nat";

let array1 = [0, 1, 2, 3];
let array2 = [0, 1, 2, 3];
Array.equal(array1, array2, equal)

Runtime: O(size1 + size2)

Space: O(1)

*Runtime and space assumes that equal runs in O(1) time and space.

Function find

func find<X>(array : [X], predicate : X -> Bool) : ?X

Returns the first value in array for which predicate returns true. If no element satisfies the predicate, returns null.

let array = [1, 9, 4, 8];
Array.find<Nat>(array, func x = x > 8)

Runtime: O(size)

Space: O(1)

*Runtime and space assumes that predicate runs in O(1) time and space.

Function append

func append<X>(array1 : [X], array2 : [X]) : [X]

Create a new array by appending the values of array1 and array2. @deprecated Array.append copies its arguments and has linear complexity; when used in a loop, consider using a Buffer, and Buffer.append, instead.

let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
Array.append<Nat>(array1, array2)

Runtime: O(size1 + size2)

Space: O(size1 + size2)

Function sort

func sort<X>(array : [X], compare : (X, X) -> Order.Order) : [X]

Sorts the elements in the array according to compare. Sort is deterministic and stable.

import Nat "mo:base/Nat";

let array = [4, 2, 6];
Array.sort(array, Nat.compare)

Runtime: O(size * log(size))

Space: O(size) *Runtime and space assumes that compare runs in O(1) time and space.

Function sortInPlace

func sortInPlace<X>(array : [var X], compare : (X, X) -> Order.Order)

Sorts the elements in the array, in place, according to compare. Sort is deterministic, stable, and in-place.


import {compare} "mo:base/Nat";

let array = [var 4, 2, 6];
Array.sortInPlace(array, compare);
array

Runtime: O(size * log(size))

Space: O(size) *Runtime and space assumes that compare runs in O(1) time and space.

Function reverse

func reverse<X>(array : [X]) : [X]

Creates a new array by reversing the order of elements in array.


let array = [10, 11, 12];

Array.reverse(array)

Runtime: O(size)

Space: O(1)

Function map

func map<X, Y>(array : [X], f : X -> Y) : [Y]

Creates a new array by applying f to each element in array. f "maps" each element it is applied to of type X to an element of type Y. Retains original ordering of elements.


let array = [0, 1, 2, 3];
Array.map<Nat, Nat>(array, func x = x * 3)

Runtime: O(size)

Space: O(size)

*Runtime and space assumes that f runs in O(1) time and space.

Function filter

func filter<X>(array : [X], predicate : X -> Bool) : [X]

Creates a new array by applying predicate to every element in array, retaining the elements for which predicate returns true.

let array = [4, 2, 6, 1, 5];
let evenElements = Array.filter<Nat>(array, func x = x % 2 == 0);

Runtime: O(size)

Space: O(size) *Runtime and space assumes that predicate runs in O(1) time and space.

Function mapEntries

func mapEntries<X, Y>(array : [X], f : (X, Nat) -> Y) : [Y]

Creates a new array by applying f to each element in array and its index. Retains original ordering of elements.


let array = [10, 10, 10, 10];
Array.mapEntries<Nat, Nat>(array, func (i, x) = i * x)

Runtime: O(size)

Space: O(size)

*Runtime and space assumes that f runs in O(1) time and space.

Function mapFilter

func mapFilter<X, Y>(array : [X], f : X -> ?Y) : [Y]

Creates a new array by applying f to each element in array, and keeping all non-null elements. The ordering is retained.

import {toText} "mo:base/Nat";

let array = [4, 2, 0, 1];
let newArray =
Array.mapFilter<Nat, Text>( // mapping from Nat to Text values
array,
func x = if (x == 0) { null } else { ?toText(100 / x) } // can't divide by 0, so return null
);

Runtime: O(size)

Space: O(size) *Runtime and space assumes that f runs in O(1) time and space.

Function mapResult

func mapResult<X, Y, E>(array : [X], f : X -> Result.Result<Y, E>) : Result.Result<[Y], E>

Creates a new array by applying f to each element in array. If any invocation of f produces an #err, returns an #err. Otherwise returns an #ok containing the new array.

let array = [4, 3, 2, 1, 0];
// divide 100 by every element in the array
Array.mapResult<Nat, Nat, Text>(array, func x {
if (x > 0) {
#ok(100 / x)
} else {
#err "Cannot divide by zero"
}
})

Runtime: O(size)

Space: O(size)

*Runtime and space assumes that f runs in O(1) time and space.

Function chain

func chain<X, Y>(array : [X], k : X -> [Y]) : [Y]

Creates a new array by applying k to each element in array, and concatenating the resulting arrays in order. This operation is similar to what in other functional languages is known as monadic bind.

import Nat "mo:base/Nat";

let array = [1, 2, 3, 4];
Array.chain<Nat, Int>(array, func x = [x, -x])

Runtime: O(size)

Space: O(size) *Runtime and space assumes that k runs in O(1) time and space.

Function foldLeft

func foldLeft<X, A>(array : [X], base : A, combine : (A, X) -> A) : A

Collapses the elements in array into a single value by starting with base and progessively combining elements into base with combine. Iteration runs left to right.

import {add} "mo:base/Nat";

let array = [4, 2, 0, 1];
let sum =
Array.foldLeft<Nat, Nat>(
array,
0, // start the sum at 0
func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!
);

Runtime: O(size)

Space: O(1)

*Runtime and space assumes that combine runs in O(1) time and space.

Function foldRight

func foldRight<X, A>(array : [X], base : A, combine : (X, A) -> A) : A

Collapses the elements in array into a single value by starting with base and progessively combining elements into base with combine. Iteration runs right to left.

import {toText} "mo:base/Nat";

let array = [1, 9, 4, 8];
let bookTitle = Array.foldRight<Nat, Text>(array, "", func(x, acc) = toText(x) # acc);

Runtime: O(size)

Space: O(1)

*Runtime and space assumes that combine runs in O(1) time and space.

Function flatten

func flatten<X>(arrays : [[X]]) : [X]

Flattens the array of arrays into a single array. Retains the original ordering of the elements.


let arrays = [[0, 1, 2], [2, 3], [], [4]];
Array.flatten<Nat>(arrays)

Runtime: O(number of elements in array)

Space: O(number of elements in array)

Function make

func make<X>(element : X) : [X]

Create an array containing a single value.

Array.make(2)

Runtime: O(1)

Space: O(1)

Function vals

func vals<X>(array : [X]) : I.Iter<X>

Returns an Iterator (Iter) over the elements of array. Iterator provides a single method next(), which returns elements in order, or null when out of elements to iterate over.

NOTE: You can also use array.vals() instead of this function. See example below.


let array = [10, 11, 12];

var sum = 0;
for (element in array.vals()) {
sum += element;
};
sum

Runtime: O(1)

Space: O(1)

Function keys

func keys<X>(array : [X]) : I.Iter<Nat>

Returns an Iterator (Iter) over the indices of array. Iterator provides a single method next(), which returns indices in order, or null when out of index to iterate over.

NOTE: You can also use array.keys() instead of this function. See example below.


let array = [10, 11, 12];

var sum = 0;
for (element in array.keys()) {
sum += element;
};
sum

Runtime: O(1)

Space: O(1)

Function size

func size<X>(array : [X]) : Nat

Returns the size of array.

NOTE: You can also use array.size() instead of this function. See example below.


let array = [10, 11, 12];
let size = Array.size(array);

Runtime: O(1)

Space: O(1)