glistix/nix/array

Contains types and functions related to Nix’s built-in lists (consisting of arrays).

Types

A Nix list. This is not a linked list, but rather a contiguous array. The fastest way to access values in this array is by index. Recursion over this type tends to be slower, as a consequence (would be O(N^2)).

pub type Array(element)

Functions

pub fn all(
  in array: Array(a),
  satisfying predicate: fn(a) -> Bool,
) -> Bool

Checks if the predicate is satisfied for all elements in the array, returning True if the function returns True for all elements, or False if it returned False for at least one element.

pub fn any(
  in array: Array(a),
  satisfying predicate: fn(a) -> Bool,
) -> Bool

Checks if the predicate is satisfied for at least one element in the array, returning True if the function returns True for one or more elements, or False if it returned False for all elements.

pub fn append(first: Array(a), second: Array(a)) -> Array(a)

Joins the second array to the end of the first using Nix’s built-in ++ operator.

Examples

append(from_list([1, 2]), from_list([7, 8]))
// -> from_list([1, 2, 7, 8])
pub fn concat(arrays: Array(Array(a))) -> Array(a)

Concatenates an array of arrays into a single array. Uses builtins.concatLists for this task.

Examples

let first = from_list([1, 2])
let second = from_list([3, 4])
let third = from_list([5])
concat(from_list([first, second, third]))
// -> from_list([1, 2, 3, 4, 5])
pub fn contains(array: Array(a), any elem: a) -> Bool

Checks if an array contains any element equal to the given value.

pub fn filter(
  array: Array(a),
  keeping predicate: fn(a) -> Bool,
) -> Array(a)

Filters the array, returning a new array containing only the elements for which the predicate function returned True.

Examples

filter(from_list([2, 3, 4, 5]), keeping: fn(x) { x > 3 })
// -> from_list([4, 5])

filter(from_list([2, 3, 4, 5]), keeping: fn(x) { x < 1 })
// -> from_list([])
pub fn filter_map(
  array: Array(a),
  with operator: fn(a) -> Result(b, c),
) -> Array(b)

Filters the array, returning a new array containing only the elements for which the given function returned Ok(new_value), replacing each with new_value.

Examples

filter_map(
  from_list([#(1, True), #(2, False), #(3, False), #(4, True)]),
  with: fn(x) {
    case x {
      #(value, True) -> Ok(value)
      #(_, False) -> Error(Nil)
    }
  }
)
// -> from_list([1, 4])

filter_map(from_list([2, 3, 4, 5]), with: Error)
// -> from_list([])

filter_map(from_list([2, 3, 4, 5]), with: fn(x) { Ok(x + 1) })
// -> from_list([3, 4, 5, 6])
pub fn find(
  in array: Array(a),
  one_that is_desired: fn(a) -> Bool,
) -> Result(a, Nil)

Finds the first element in the array for which the function returns True.

If no such element exists, returns Error(Nil).

Note that, currently, this will always traverse the whole array.

Examples

find(from_list([1, 2, 3, 4, 5]), fn(x) { x > 3 })
// -> Ok(4)

find(from_list([10]), fn(x) { x == 5 })
// -> Error(Nil)
pub fn find_map(
  in array: Array(a),
  with operator: fn(a) -> Result(b, c),
) -> Result(b, Nil)

Finds the first element in the array for which the function returns Ok(new_value), and then returns Ok(new_value).

If no such element exists (that is, the function returns Error(_) for all elements in the array, or it is empty), returns Error(Nil).

Note that, currently, this will always traverse the whole array.

Examples

find_map(
  from_list([#(1, False), #(2, False), #(3, True), #(4, True)]), fn(x) {
    case x {
      #(value, True) -> Ok(value)
      #(_, False) -> Error(Nil)
    }
  })
)
// -> Ok(3)

find_map(from_list([from_list([]), from_list([10]), from_list([12, 13])), first)
// -> Ok(10)

find_map(from_list([from_list([]), from_list([])]), first)
// -> Error(Nil)

find_map(from_list([]), first)
// -> Error(Nil)
pub fn first(array: Array(a)) -> Result(a, Nil)

Returns the first element of the array, if it isn’t empty.

Examples

first(from_list([]))
// -> Error(Nil)

first(from_list([1]))
// -> Ok(1)

first(from_list([2, 3, 4]))
// -> Ok(2)
pub fn flat_map(
  over array: Array(a),
  with operator: fn(a) -> Array(b),
) -> Array(b)

Similar to map, but flattens the resulting array of arrays after mapping.

This function is more efficient than a map followed by flatten, as it uses the built-in builtins.concatMap function.

Examples

flat_map(from_list([8, 9, 10]), fn(x) { from_list([x, x - 1, x * 2]) })
// -> from_list([8, 7, 16, 9, 8, 18, 10, 9, 20])
pub fn flatten(arrays: Array(Array(a))) -> Array(a)

This is the same as concat, which joins an array of arrays into a single array.

Examples

let first = from_list([1, 2])
let second = from_list([3, 4])
let third = from_list([5])
flatten(from_list([first, second, third]))
// -> from_list([1, 2, 3, 4, 5])
pub fn fold(
  over array: Array(a),
  from init: b,
  with operator: fn(b, a) -> b,
) -> b

Reduces a list of elements into a single value by calling a given function on each element, going from start to end.

Runs in linear time, and is strict (uses the foldl' built-in).

pub fn fold_right(
  over array: Array(a),
  from init: b,
  with operator: fn(b, a) -> b,
) -> b

Reduces a list of elements into a single value by calling a given function on each element, going from end to start.

Runs in linear time, and is lazy and recursive, so large arrays can cause a stack overflow.

pub fn from_iterator(iterator: Iterator(a)) -> Array(a)

Converts a Gleam iterator to a Nix array.

Runs in linear time.

pub fn from_list(list: List(a)) -> Array(a)

Converts a Gleam list to a Nix array.

Runs in linear time, and is recursive, so large lists can cause a stack overflow.

pub fn generate(
  length: Int,
  with generator: fn(Int) -> a,
) -> Array(a)

Generates an array with a specified length. Takes a function which specifies a value for each index in the new array.

Runs in linear time, but is not recursive (uses the built-in genList function).

pub fn get(array: Array(a), at index: Int) -> Result(a, Nil)

Get the element at the given index.

Examples

get(from_list([1, 2, 3]), 0)
// -> Ok(1)

get(from_list([1, 2, 3]), 2)
// -> Ok(3)

get(from_list([1, 2, 3]), 3)
// -> Error(Nil)
pub fn index_fold(
  over array: Array(a),
  from initial: b,
  with operator: fn(b, a, Int) -> b,
) -> b

Similar to fold, but the function receives each element’s index alongside the accumulator and the element.

Runs in linear time and is strict.

pub fn index_map(
  over array: Array(a),
  with operator: fn(a, Int) -> b,
) -> Array(b)

Similar to map, but the function receives each element as well as its index.

Runs in linear time.

pub fn map(
  over array: Array(a),
  with operator: fn(a) -> b,
) -> Array(b)

Returns a new array containing only the elements of the first array after the function has been applied to each one.

Runs in linear time.

pub fn new() -> Array(a)

Creates a new, empty array.

pub fn partition(
  array: Array(a),
  with categorise: fn(a) -> Bool,
) -> #(Array(a), Array(a))

Partitions an array’s elements into a pair of arrays based on the output of the given function. The first array returned includes elements for which the function returned True, while the second array includes elements for which the function returned False.

pub fn range(from start: Int, to stop: Int) -> Array(Int)

Creates an array of integers from start to finish, inclusive.

Examples

range(0, 0)
// -> from_list([0])

range(0, 5)
// -> from_list([0, 1, 2, 3, 4, 5])

range(1, -5)
// -> from_list([1, 0, -1, -2, -3, -4, -5])
pub fn reduce(
  over array: Array(a),
  with operator: fn(a, a) -> a,
) -> Result(a, Nil)

Similar to fold, but the initial value of the accumulator is the first element in the array. Returns Error(Nil) if the array was empty.

Examples

reduce(over: from_list([1, 2, 3]), with: fn(a, b) { a + b })
// -> Ok(6)

reduce(over: from_list([]), with: fn(a, b) { a + b })
// -> Error(Nil)
pub fn rest(array: Array(a)) -> Result(Array(a), Nil)

Returns the array minus its first element, or Error(Nil) if it is empty.

Note that this runs in linear time, so using rest with a recursive algorithm will yield O(n^2) complexity. Consider using increasing indices to access the array instead, if possible. Alternatively, use a List with such algorithms instead, as the equivalent operation over List runs in constant time (while indexing over a List runs in linear time).

Examples

rest(from_list([]))
// -> Error(Nil)

rest(from_list([1]))
// -> Ok(from_list([]))

rest(from_list([1, 2]))
// -> Ok(from_list([2]))
pub fn reverse(array: Array(a)) -> Array(a)

Reverses the array, returning a new array with its elements in the opposite order as the given array.

Runs in linear time.

Examples

reverse(from_list([1, 2, 3, 4]))
// -> from_list([4, 3, 2, 1])
pub fn single(item: a) -> Array(a)

Creates an array with one element.

Examples

single(5)
// -> from_list([5])
pub fn size(array: Array(a)) -> Int

Gets the amount of elements in the array.

Runs in constant time.

pub fn sized_chunk(
  in array: Array(a),
  into count: Int,
) -> Array(Array(a))

Splits an array’s elements into chunks of fixed size. If the chunk size doesn’t evenly divide the array length, the last chunk will be incomplete, containing only the remaining elements.

Specifying a chunk size smaller than 1 is the same as specifying 1.

Examples

from_list([1, 2, 3, 4, 5, 6]) |> sized_chunk(into: 2)
// -> from_list([from_list([1, 2]), from_list([3, 4]), from_list([5, 6])])

from_list([1, 2, 3, 4, 5, 6, 7, 8]) |> sized_chunk(into: 3)
// -> from_list([from_list([1, 2, 3]), from_list([4, 5, 6]), from_list([7, 8])])
pub fn slice(
  from array: Array(a),
  at position: Int,
  take length: Int,
) -> Result(Array(a), Nil)

Takes a specific portion of an array, slicing from the given position and stopping after the given length, generating a new array. Negative lengths can be used to take from the end of the array. If the slicing would go out of bounds, returns an error.

Examples

slice(from: from_list([1, 2, 3, 4]), at: 1, take: 2)
// -> Ok(from_list([2, 3]))

slice(from: from_list([1, 2, 3, 4]), at: 4, take: -3)
// -> Ok(from_list([2, 3, 4]))

slice(from: from_list([]), at: 1, take: 2)
// -> Error(Nil)
pub fn sort(
  array: Array(a),
  by compare: fn(a, a) -> Order,
) -> Array(a)

Sorts an array using the built-in sort function through the given comparator. Sorts in ascending order by default, but the order can be reversed through order.reverse in the standard library.

This uses a stable sort algorithm, meaning elements which compare equal preserve their relative order.

Examples

sort(from_list([3, 10, 4, 32]), by: int.compare)
// -> from_list([32, 10, 4, 3])

sort(from_list([3, 10, 4, 32]), by: order.reverse(int.compare))
// -> from_list([3, 4, 10, 32])
pub fn split(
  array: Array(a),
  at index: Int,
) -> #(Array(a), Array(a))

Splits an array in two before the given index. If the array isn’t long enough to contain that index, the first returned array will be equal to the full given array, and the second returned array will be empty.

Examples

split(from_list([12, 34, 56]), at: 0)
// -> #(from_list([]), from_list([12, 34, 56]))

split(from_list([12, 34, 56]), at: 1)
// -> #(from_list([12]), from_list([34, 56]))

split(from_list([12, 34, 56]), at: 3)
// -> #(from_list([12, 34, 56]), from_list([]))
pub fn to_iterator(array: Array(a)) -> Iterator(a)

Converts a Nix array to a Gleam iterator.

pub fn to_list(array: Array(a)) -> List(a)

Converts a Nix array to a Gleam list.

Runs in linear time.

pub fn transpose(rows: Array(Array(a))) -> Array(Array(a))

Transpose rows and columns of the array of arrays.

Traverses the array once to determine the amount of columns, and then traverses again for each column.

Examples

transpose(from_list([from_list([1, 2, 3]), from_list([4, 5, 6]), from_list([7, 8, 9])]))
// -> from_list([from_list([1, 4, 7]), from_list([2, 5, 8]), from_list(3, 6, 9)])
pub fn unzip(input: Array(#(a, b))) -> #(Array(a), Array(b))

Takes an array of 2-element tuples and returns two arrays.

Examples

unzip(from_list([#(1, 2), #(3, 4)]))
// -> #(from_list([1, 3]), from_list([2, 4]))

unzip([])
// -> #(from_list([]), from_list([]))
pub fn zip(
  first: Array(a),
  with second: Array(b),
) -> Array(#(a, b))

Combines two arrays into an array of 2-element tuples, where the tuple at position ‘i’ contains element ‘i’ from the first array and element ‘i’ from the second array.

If one array is longer than the other, the returned array will have the size of the shortest, with the longer array’s extra items being ignored.

Examples

zip(from_list([1, 2]), from_list([3, 4]))
// -> from_list([#(1, 3), #(2, 4)])

zip(from_list([1, 2]), from_list([3]))
// -> from_list([#(1, 3)])

zip(from_list([1, 2]), from_list([]))
// -> from_list([])
Search Document