std.array
all : forall a. (a -> Bool) -> Array a -> Bool
Returns true if all elements in the given array satisfy the predicate,
false otherwise.
Examples
std.array.all (fun x => x < 3) [ 1, 2 ]
# => true
std.array.all (fun x => x < 3) [ 1, 2, 3 ]
# => false
any : forall a. (a -> Bool) -> Array a -> Bool
Returns true if at least one element in the given array satisfies
the predicate, false otherwise.
Examples
std.array.any (fun x => x < 3) [ 1, 2, 3, 4 ]
# => true
std.array.any (fun x => x < 3) [ 5, 6, 7, 8 ]
# => false
append : forall a. a -> Array a -> Array a
Builds an array given the last element and the rest of the array.
Examples
std.array.append 3 [ 1, 2 ]
# => [ 1, 2, 3 ]
at : forall a. Number -> Array a -> a
at | std.contract.unstable.IndexedArrayFun 'Index
Retrieves the n-th element from an array, with indices starting at 0.
Examples
std.array.at 3 [ "zero", "one", "two", "three", "four" ]
# => "three"
at_or : forall a. Number -> a -> Array a -> a
at_or | std.number.Nat -> Dyn
Retrieves the n-th element from an array, with indices starting at 0 or the provided default value if the index is greater than the length of the array.
Examples
std.array.at_or 3 "default" [ "zero", "one", "two", "three" ]
# => "three"
std.array.at_or 3 "default" [ "zero", "one" ]
# => "default"
compare : forall
a.
(a -> a -> [| 'Lesser, 'Equal, 'Greater |])
-> Array a -> Array a -> [| 'Lesser, 'Equal, 'Greater |]
compare order a b lexicographically compares a and b, using order to
compare the individual elements.
Examples
std.array.compare std.number.compare [3, 1, 4] [6, 2, 8]
# => 'Lesser
std.array.compare std.string.compare ["hello", "world"] ["hello"]
# => 'Greater
concat : forall a. Array a -> Array a -> Array a
Appends the second array to the first one.
Examples
std.array.concat [ 1, 2, 3 ] [ 4, 5, 6 ]
# => [ 1, 2, 3, 4, 5, 6 ]
dedup : Array Dyn -> Array Dyn
Removes duplicates from an array.
Performance
This function relies on equality and has a quadratic complexity in the
length of the array. It might thus be slow for large arrays or if
called repeatedly. Prefer std.array.sort_dedup or
std.array.dedup_sorted if you have efficiency concerns.
Examples
std.array.dedup [ 4, 2, 1, 3, 5, 2, 1, 4 ]
# => [ 4, 2, 1, 3, 5 ]
std.array.dedup [ "hello", "world", "hello" ]
# => [ "hello", "world" ]
dedup_sorted : forall a. (a -> a -> [| 'Lesser, 'Equal, 'Greater |]) -> Array a -> Array a
Given an array already sorted by the given ordering function, remove duplicates.
Preconditions
The input array must be sorted using the same order as provided to this function. Otherwise, some duplicates might not be removed.
Performance
As opposed to std.array.dedup, this function has a linear time
complexity, which should improve performance especially on large arrays.
If you sort the array only to remove duplicates, you can use
std.array.sort_dedup directly (which handles both sorting and
deduplication).
Examples
std.array.dedup_sorted std.number.compare [ 1, 2, 2, 3, 4, 4, 4, 5 ]
# => [ 1, 2, 3, 4, 5 ]
std.array.dedup_sorted std.string.compare [ "hello", "world", "world" ]
# => [ "hello", "world" ]
drop_first : forall a. Array a -> Array a
drop_first | NonEmpty -> Dyn
Returns the given array without its first element.
Examples
std.array.drop_first [ 1, 2, 3 ]
# => [ 2, 3 ]
drop_last : forall a. Array a -> Array a
drop_last | NonEmpty -> Dyn
Returns the given array without its last element.
Examples
std.array.drop_last [ 1, 2, 3 ]
# => [ 1, 2 ]
elem : Dyn -> Array Dyn -> Bool
Returns true if the given value appears in the array, false otherwise.
Examples
std.array.elem 3 [ 1, 2, 3, 4, 5 ]
# => true
filter : forall a. (a -> Bool) -> Array a -> Array a
filter f xs returns an array containing all elements from xs that satisfy f.
Examples
std.array.filter (fun x => x <= 3) [ 4, 3, 2, 5, 1 ]
# => [ 3, 2, 1 ]
filter_map : forall a b. (a -> [| 'Some b, 'None |]) -> Array a -> Array b
Applies a function to every element in the given array, filtering out
'None results. filter_map combines std.array.map and
std.array.filter in a single pass.
Examples
["1", "hello", "2", "world"]
|> std.array.filter_map (fun x =>
if std.string.is_match "^[+-]?\\d+$" x then
'Some (std.string.to_number x)
else
'None
)
# => [ 1, 2 ]
first : forall a. Array a -> a
first | NonEmpty -> Dyn
Returns the first element of an array.
Examples
std.array.first [ "this is the head", "this is not" ]
# => "this is the head"
flat_map : forall a b. (a -> Array b) -> Array a -> Array b
First map the given function over the array and then flatten the
result.
Examples
std.array.flat_map (fun x => [x, x]) [1, 2, 3]
# => [1, 1, 2, 2, 3, 3]
flatten : forall a. Array (Array a) -> Array a
Concatenates all elements of an array of arrays.
Examples
std.array.flatten [[1, 2], [3, 4]]
# => [1, 2, 3, 4]
fold_left : forall a b. (a -> b -> a) -> a -> Array b -> a
Folds a function over an array. In a functional language like Nickel,
folds serve a similar purpose to loops or iterators. fold_left
iterates over an array, by repeatedly applying a function to each
element, threading an additional arbitrary state (the accumulator, of
type a in the signature) through the chain of applications.
fold_left f init [x1, x2, ..., xn] results in f (... (f (f init x1) x2) ...) xn.
This function is strict in the intermediate accumulator.
Left vs right
Folds come in two variants, left and right. How to decide which one to use?
-
If the folded function isn't associative (such as subtraction), then each variant will give a different result. The choice is dictacted by which one you need. For example:
std.array.fold_right (-) 0 [1, 2, 3, 4] # => -2std.array.fold_left (-) 0 [1, 2, 3, 4] # => -10 -
If the folded function is associative, both
fold_rightandfold_leftreturn the same result. In that case,fold_leftis generally preferred, because it forces the evaluation of the intermediate results resulting in less memory consumption and overall better performance (outside of pathological cases).fold_leftalso iterates from the start of the array, which correponds to the usual behavior of loops and iterators in most programming languages. There is one case wherefold_rightmight be preferred, see the next point. -
If the folded function is associative but (left) short-circuiting, meaning that it can sometimes determine the result without using the right argument, then
fold_rightprovides early return. An example is the boolean AND operator&&: when evaluatingleft && right, ifleftisfalse, the whole expression will evaluate tofalsewithout even evaluatingright. Consider the following expression:std.array.replicate 1000 true # gives [false, .. true 1000 times] |> std.array.prepend false |> std.array.fold_right (&&) [false]Here,
fold_rightwill stop at the first element, and the operation runs in constant time, given the definition offold_rightand the lazy evaluation of Nickel. If we had usedfold_leftinstead, which is closer to a standard iterator, we would have iterated over all of the 1000 elements of the array.
Examples
fold_left (fun acc e => acc + e) 0 [ 1, 2, 3 ]
# => (((0 + 1) + 2) + 3)
# => 6
fold_right : forall a b. (a -> b -> b) -> b -> Array a -> b
Folds a function over an array. Folds serve a similar purpose to loops or
iterators in a functional language like Nickel. fold_right iterates
over an array by repeatedly applying a function to each element and
threading an additional arbitrary state (the accumulator of type a in
the signature) through the chain of applications.
fold_right f init [x1, x2, ..., xn] results in f x1 (f x2 (... (f xn init) ...)).
Left vs right
Folds come in two variants, left and right. How to decide which one to
use? Please refer to the documentation of fold_left.
Examples
std.array.fold_right (fun e acc => acc @ [e]) [] [ 1, 2, 3 ]
# => ((([] @ [3]) @ [2]) @ [1])
# => [ 3, 2, 1 ]
generate : forall a. (Number -> a) -> Number -> Array a
generate | Dyn -> std.number.Nat -> Dyn
generate f n returns an array of length n by applying f to the
integers from 0 to n-1. That is, generate f n is
[ f 0, f 1, ..., f (n - 1)]
Examples
std.array.generate (fun x => x * x) 4
# => [ 0, 1, 4, 9 ]
intersperse : forall a. a -> Array a -> Array a
Intersperses a value between the elements of an array.
Examples
std.array.intersperse ", " [ "Hello", "wonderful", "world!" ]
# => [ "Hello", ", ", "wonderful", ", ", "world!" ]
std.array.intersperse ", " [ "Hello" ]
# => [ "Hello" ]
std.array.intersperse ", " []
# => []
last : forall a. Array a -> a
last | NonEmpty -> Dyn
Returns the last element of an array.
Examples
std.array.last [ "this is the head", "this is not" ]
# => "this is not"
length : forall a. Array a -> Number
Returns the length of an array.
Examples
std.array.length [ "Hello,", " World!" ]
# => 2
map : forall a b. (a -> b) -> Array a -> Array b
Applies a function to every element in the given array. That is,
map f [ x1, x2, ..., xn ] is [ f x1, f x2, ..., f xn ].
Examples
std.array.map (fun x => x + 1) [ 1, 2, 3 ]
# => [ 2, 3, 4 ]
map_with_index : forall a b. (Number -> a -> b) -> Array a -> Array b
Applies a function to every element in the given array while passing
its (0-based) index. That is,
map_with_index f [ x1, x2, ... ] is [ f 0 x1, f 1 x2, ... ].
Examples
std.array.map_with_index (fun i x => i + x + 1) [ 1, 2, 3 ]
# => [ 2, 4, 6 ]
NonEmpty
Enforces that an array is not empty.
Examples
([] | std.array.NonEmpty)
# => error: contract broken by a value
([ 1 ] | std.array.NonEmpty)
# => [ 1 ]
partition : forall a. (a -> Bool) -> Array a -> { right : Array a, wrong : Array a }
Partitions an array into two new arrays. right will contain all
elements that satisfy the predicate, while wrong will contain those
that do not.
Examples
std.array.partition (fun x => x < 5) [ 2, 4, 5, 3, 7, 8, 6 ]
# => { right = [ 2, 4, 3 ], wrong = [ 5, 7, 8, 6 ] }
prepend : forall a. a -> Array a -> Array a
Builds an array given the first element and the rest of the array.
Examples
std.array.prepend 1 [ 2, 3 ]
# => [ 1, 2, 3 ]
range : Number -> Number -> Array Number
range | std.contract.unstable.RangeFun Dyn
range start end generates the array of numbers
[start, start + 1, start + 2, ..] up to the first element
(excluded) larger than or equal to end.
range start end is equivalent to range_step start end 1.
Preconditions
In range_step start end, start and end must satisfy
start <= end.
Examples
std.array.range 0 5
# => [ 0, 1, 2, 3, 4 ]
range_step : Number -> Number -> Number -> Array Number
range_step | std.contract.unstable.RangeFun (std.contract.unstable.RangeStep -> Dyn)
range_step start end step generates the array of numbers
[start, start + step, start + 2*step, ..] up to the first element
(excluded) larger than or equal to end
Preconditions
In range_step start end step, start and end must satisfy start <= end. step must be strictly greater than 0.
Examples
std.array.range_step (-1.5) 2 0.5
# => [ -1.5, -1, -0.5, 0, 0.5, 1, 1.5 ]
reduce_left : forall a. (a -> a -> a) -> Array a -> a
reduce_left | Dyn -> NonEmpty -> Dyn
Reduces the elements to a single one, by repeatedly applying a reducing operation.
reduce_left associates to the left, that is
reduce_left op [x1, x2, ..., xn] results in op (... (op (op x1 x2) x3) ...) xn.
reduce_left is the same as fold_left, but uses the first element as
the initial accumulator.
Preconditions
The provided array must be non-empty.
Left vs right
The rationale to decide between fold_left and fold_right applies to
reduce_left and reduce_right as well. See the documentation of
fold_left.
Examples
std.array.reduce_left (@) [ [1, 2], [3], [4,5] ]
# => (([1, 2] @ [3]) @ [4,5])
# => [ 1, 2, 3, 4, 5 ]
std.array.reduce_left (-) [ 1, 2, 3, 4]
# => ((1 - 2) - 3) - 4
# => -8
reduce_right : forall a. (a -> a -> a) -> Array a -> a
reduce_right | Dyn -> NonEmpty -> Dyn
Reduces the elements to a single one, by repeatedly applying a reducing operation.
reduce_right associates to the right, that is
reduce_right op [x1, x2, ..., xn] results in
op x1 (op x2 (... (op xn-1 xn) ...)).
reduce_right is the same as fold_right, but uses the last element as
the initial element.
Preconditions
The provided array must be non-empty.
Left vs right
The rationale to decide between fold_left and fold_right applies to
reduce_left and reduce_right as well. See the documentation of
fold_left.
Examples
std.array.reduce_right (@) [ [1, 2], [3], [4,5] ]
# => [1, 2] @ ([3] @ [4,5])
# => [ 1, 2, 3, 4, 5 ]
std.array.reduce_right (-) [ 1, 2, 3, 4]
# => 1 - (2 - (3 - 4))
# => -2
replicate : forall a. Number -> a -> Array a
replicate | std.number.Nat -> Dyn
replicate n x creates an array containing x exactly n times.
Preconditions
n must be an integer greater or equal to 0.
Examples
std.array.replicate 0 false
# => [ ]
std.array.replicate 5 "x"
# => [ "x", "x", "x", "x", "x" ]
reverse : forall a. Array a -> Array a
Reverses an array.
Examples
std.array.reverse [ 1, 2, 3 ]
# => [ 3, 2, 1 ]
slice : forall a. Number -> Number -> Array a -> Array a
slice | std.contract.unstable.ArraySliceFun
slice start end array returns the slice of array between start (included) and
end (excluded).
Preconditions
In slice start end value, start and end must be positive
integers such that 0 <= start <= end <= std.array.length value.
Examples
std.array.slice 1 3 [ 0, 1, 2, 3, 4, 5]
# => [ 1, 2 ]
std.array.slice 0 3 [ "Hello", "world", "!" ]
# => [ "Hello", "world", "!" ]
std.array.slice 2 3 [ "Hello", "world", "!" ]
# => [ "!" ]
sort : forall a. (a -> a -> [| 'Lesser, 'Equal, 'Greater |]) -> Array a -> Array a
Sorts an array based on the provided comparison operator.
Examples
std.array.sort (fun x y =>
if x < y then
'Lesser
else if (x == y) then
'Equal
else
'Greater)
[ 4, 5, 1, 2 ]
# => [ 1, 2, 4, 5 ]
sort_dedup : forall a. (a -> a -> [| 'Lesser, 'Equal, 'Greater |]) -> Array a -> Array a
Sorts an array based on the provided comparison operator and removes duplicates.
This is a combination of std.array.sort and std.array.dedup_sorted.
Performance
As opposed to std.array.dedup, this function has a better time
complexity (O(n*log(n)) where n is the size of the array), which
should improve performance especially on large arrays.
Examples
std.array.sort_dedup std.number.compare [ 4, 2, 1, 3, 5, 2, 1, 4 ]
# => [ 1, 2, 3, 4, 5 ]
std.array.sort_dedup std.string.compare [ "world", "hello", "world" ]
# => [ "hello", "world" ]
split_at : forall a. Number -> Array a -> { left : Array a, right : Array a }
split_at | std.contract.unstable.IndexedArrayFun 'Split
Splits an array in two at a given index and puts all the elements
to the left of the element at the given index (excluded) in the
left field, and the rest of the array in the right field.
Preconditions
In split_at index value, index must be a positive integer such
that 0 <= index <= std.array.length value.
Examples
std.array.split_at 2 [ 0, 1, 2, 3, 4, 5]
# => { left = [ 0, 1 ], right = [ 2, 3, 4, 5 ] }
std.array.split_at 0 [ "Hello", "world", "!" ]
# => { left = [ ], right = [ "Hello", "world", "!" ] }
std.array.split_at 3 [ "Hello", "world", "!" ]
# => { left = [ "Hello", "world", "!" ], right = [ ] }
try_fold_left : forall
a
b
c.
(a -> c -> [| 'Ok a, 'Error b |]) -> a -> Array c -> [| 'Ok a, 'Error b |]
Folds a function over an array from left to right, possibly stopping early.
This differs from fold_left in that the function being folded returns either
'Error y (meaning that the folding should terminate, immediately returning
'Error y) or 'Ok acc (meaning that the folding should continue as usual,
with the new accumulator acc). This early return can be used as an optimization,
to avoid evaluating the whole array.
Examples
This defines a function that returns the first element satisfying a predicate.
let find_first: forall a. (a -> Bool) -> Array a -> [| 'Some a, 'None |]
= fun pred xs =>
# Our fold function, which just ignores the accumulator and immediately
# returns an element if it satisfies the predicate. Note that `'Error`
# (which is the short-circuiting branch) means that we found something.
let f = fun _acc x => if pred x then 'Error x else 'Ok null in
try_fold_left f null xs |> match {
'Ok _ => 'None,
'Error x => 'Some x,
}
in
let even = fun x => x % 2 == 0 in
find_first even [1, 3, 4, 5, 2]
# => 'Some 4
zip_with : forall a b c. (a -> b -> c) -> Array a -> Array b -> Array c
zip_with f xs ys combines the arrays xs and ys using the
operation f. The resulting array's length will be the smaller of the
lengths of xs and ys.
Examples
std.array.zip_with (+) [1, 2, 3] [4, 5, 6]
# => [5, 7, 9]
std.array.zip_with (*) [1, 2] [4, 5, 6]
# => [4, 10]
std.array.zip_with (-) [1, 2, 3] [4, 5]
# => [-3, -3]