aiken/collection/list
Types
Functions
Constructing
Add an element in front of the list. Sometimes useful when combined with
other functions.
list.push([2, 3], 1) == [1, ..[2, 3]] == [1, 2, 3]
Construct a list of a integer from a given range.
list.range(0, 3) == [0, 1, 2, 3]
list.range(-1, 1) == [-1, 0, 1]
Construct a list filled with n copies of a value.
list.repeat("na", 3) == ["na", "na", "na"]
Inspecting
Determine if all elements of the list satisfy the given predicate.
An empty list always satisfies the predicate.
list.all([], fn(n) { n > 0 }) == True
list.all([1, 2, 3], fn(n) { n > 0 }) == True
list.all([1, 2, 3], fn(n) { n == 2 }) == False
Determine if at least one element of the list satisfies the given predicate.
An empty list NEVER satisfies the predicate.
list.any([], fn(n) { n > 2 }) == False
list.any([1, 2, 3], fn(n) { n > 0 }) == True
list.any([1, 2, 3], fn(n) { n == 2 }) == True
list.any([1, 2, 3], fn(n) { n < 0 }) == False
Return Some(item) at the index or None if the index is out of range. The index is 0-based.
list.at([1, 2, 3], 1) == Some(2)
list.at([1, 2, 3], 42) == None
Count how many items in the list satisfy the given predicate.
list.count([], fn(a) { a > 2}) == 0
list.count([1, 2, 3], fn(a) { n > 0 }) == 3
list.count([1, 2, 3], fn(a) { n >= 2 }) == 2
list.count([1, 2, 3], fn(a) { n > 5 }) == 0
Find the first element satisfying the given predicate, if any.
list.find([1, 2, 3], fn(x) { x == 2 }) == Some(2)
list.find([4, 5, 6], fn(x) { x == 2 }) == None
Like find, but maps the found element to something else. This
provides an efficient way to access and transform an element in a list.
expect Some(2) = list.find_map(["a", "bb", "ccc"], fn(x) {
let len = bytearray.length(x)
if len > 1 {
Some(len)
} else {
None
}
})
Figures out whether a list contain the given element.
list.has([1, 2, 3], 2) == True
list.has([1, 2, 3], 14) == False
list.has([], 14) == False
Get the first element of a list
list.head([1, 2, 3]) == Some(1)
list.head([]) == None
Checks whether a list is empty.
list.is_empty([]) == True
list.is_empty([1, 2, 3]) == False
Gets the index of an element of a list, if any. Otherwise, returns None.
list.index_of([1, 5, 2], 2) == Some(2)
list.index_of([1, 7, 3], 4) == None
list.index_of([1, 0, 9, 6], 6) == Some(3)
list.index_of([], 6) == None
Get the last in the given list, if any.
list.last([]) == None
list.last([1, 2, 3]) == Some(3)
Get the number of elements in the given list.
list.length([]) == 0
list.length([1, 2, 3]) == 3
Inspecting Forcibly
More efficient version of any, but fails if no element satisfies the predicate.
An empty list NEVER satisfies the predicate.
list.any([], fn(n) { n > 2 }) β π₯
list.any([1, 2, 3], fn(n) { n > 0 }) == True
list.any([1, 2, 3], fn(n) { n == 2 }) == True
list.any([1, 2, 3], fn(n) { n < 0 }) β π₯
More efficient version of at, but fails if thereβs no element at the
given index (or if the index is out of bound).
list.expect_at([1, 2, 3], 1) == 2
list.expect_at([1, 2, 3], 42) β π₯
More efficient version of find, but fails if the element is not found.
list.expect_find([1, 2, 3], fn(x) { x == 2 }) == 2
list.expect_find([4, 5, 6], fn(x) { x == 2 }) β π₯
More efficient version of find_map but fails if no element
is selected.
expect 2 = list.expect_find_map(["a", "bb", "ccc"], fn(x, keep, discard) {
let len = bytearray.length(x)
if len > 1 {
keep(len)
} else {
discard()
}
})
More efficient version of has but fails if the element is missing.
list.expect_has([1, 2, 3], 2) β β
list.expect_has([1, 2, 3], 14) β π₯
list.expect_has([], 14) β π₯
More efficient version of head, but fails if the list is empty.
list.expect_head([1, 2, 3]) == 1
list.expect_head([]) β π₯
More efficient version of index_of, but fails if the element
is not in the list.
list.expect_index_of([1, 5, 2], 2) == 2
list.expect_index_of([1, 7, 3], 4) β π₯
list.expect_index_of([1, 0, 9, 6], 6) == 3
list.expect_index_of([], 6) β π₯
More efficient version of last, but fails when the list is empty.
list.expect_last([1, 2, 3]) == 3
list.expect_last([]) β π₯
Modifying
Extracting
Remove the first occurrence of the given element from the list.
list.delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.delete([1, 2, 3], 14) == [1, 2, 3]
Drop the first n elements of a list.
list.drop([1, 2, 3], 2) == [3]
list.drop([], 42) == []
list.drop([1, 2, 3], 42) == []
Returns the suffix of the given list after removing all elements that satisfy the predicate.
list.drop_while([1, 2, 3], fn(x) { x < 2 }) == [2, 3]
list.drop_while([], fn(x) { x > 2 }) == []
list.drop_while([1, 2, 3], fn(x) { x == 3 }) == [1, 2, 3]
Produce a list of elements that satisfy a predicate.
list.filter([1, 2, 3], fn(x) { x >= 2 }) == [2, 3]
list.filter([], fn(x) { x > 2 }) == []
list.filter([1, 2, 3], fn(x) { x == 3 }) == [3]
Produce a list of transformed elements that satisfy a predicate.
let transform = fn(x) { if x % 2 == 0 { None } else { Some(3*x) } }
list.filter_map([1, 2, 3], transform) == [3, 9]
Return all elements except the last one.
list.init([]) == None
list.init([1, 2, 3]) == Some([1, 2])
Returns a tuple with all elements that satisfy the predicate at first
element, and the rest as second element.
list.partition([1, 2, 3, 4], fn(x) { x % 2 == 0 }) == ([2, 4], [1, 3])
Extract a sublist from the given list using 0-based indexes. Negative
indexes wrap over, so -1 refers to the last element of the list.
list.slice([1, 2, 3, 4, 5, 6], from: 2, to: 4) == [3, 4, 5]
list.slice([1, 2, 3, 4, 5, 6], from: -2, to: -1) == [5, 6]
list.slice([1, 2, 3, 4, 5, 6], from: 1, to: -1) == [2, 3, 4, 5, 6]
Cut a list in two, such that the first list contains the given number of /
elements and the second list contains the rest.
Fundamentally equivalent to (but more efficient):
// span(xs, n) == (take(xs, n), drop(xs, n))
span([1, 2, 3, 4, 5], 3) == ([1, 2, 3], [4, 5])
Get elements of a list after the first one, if any.
list.tail([]) == None
list.tail([1, 2, 3]) == Some([2, 3])
Get the first n elements of a list.
list.take([1, 2, 3], 2) == [1, 2]
list.take([1, 2, 3], 14) == [1, 2, 3]
Returns the longest prefix of the given list where all elements satisfy the predicate.
list.take_while([1, 2, 3], fn(x) { x > 2 }) == []
list.take_while([1, 2, 3], fn(x) { x < 2 }) == [1]
Removes duplicate elements from a list.
list.unique([1, 2, 3, 1]) == [1, 2, 3]
Extracting Forcibly
More efficient version of delete, which also fails when the element is NOT in the list.
list.expect_delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.expect_delete([1, 2, 3], 14) β π₯
More efficient version of drop, which fails when thereβs less than n elements in the list.
Yields the list when n is negative.
More efficient version of init, which fails when the list is empty.
More efficient version of tail, which fails when the list is empty.
More efficient version of take, which fails when the list contains less element than wanted.
Yields an empty list when n is negative.
Mapping
More efficient
Map elements of a list into a new list and flatten the result.
list.flat_map([1, 2, 3], fn(a) { [a, 2*a] }) == [1, 2, 2, 4, 3, 6]
Perform an action for each element of a list.
list.for_each(labels, do: fn(lbl) { trace lbl Void })
List map but provides the position (0-based) of the elements while iterating.
list.indexed_map([1, 2, 3], fn(i, x) { i + x }) == [1, 3, 5]
Apply a function to each element of a list.
list.map([1, 2, 3, 4], fn(n) { n + 1 }) == [2, 3, 4, 5]
Apply a function of two arguments, combining elements from two lists.
If one list is longer, the extra elements are dropped.
list.map2([1, 2, 3], [1, 2], fn(a, b) { a + b }) == [2, 4]
Apply a function of three arguments, combining elements from three lists.
If one list is longer, the extra elements are dropped.
list.map3([1, 2, 3], [1, 2], [1, 2, 3], fn(a, b, c) { a + b + c }) == [3, 6]
Return the list with its elements in the reserve order.
list.reverse([1, 2, 3]) == [3, 2, 1]
Sort a list in ascending order using the given comparison function.
use aiken/primitive/int
list.sort([3, 1, 4, 0, 2], int.compare) == [0, 1, 2, 3, 4]
list.sort([1, 2, 3], int.compare) == [1, 2, 3]
Decompose a list of tuples into a tuple of lists.
list.unzip([(1, "a"), (2, "b")]) == ([1, 2], ["a", "b"])
Combining
Merge two lists together.
list.concat([], []) == []
list.concat([], [1, 2, 3]) == [1, 2, 3]
list.concat([1, 2, 3], [4, 5, 6]) == [1, 2, 3, 4, 5, 6]
Remove the first occurrence of each element of the second list from the first one.
list.difference(["h", "e", "l", "l", "o"], ["l", "e", "l"]) == ["h", "o"]
list.difference([1, 2, 3, 4, 5], [1, 1, 2]) == [3, 4, 5]
list.difference([1, 2, 3], []) == [1, 2, 3]
Combine two lists together.
If one list is longer, the extra elements are dropped.
list.zip([1, 2], ["a", "b", "c"]) == [(1, "a"), (2, "b")]
Transforming
Reduce a list from left to right.
list.foldl([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldl([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [3, 2, 1]
foldl2(
self: List<elem>,
zero_a: a,
zero_b: b,
with: fn(elem, a, b, Fold2<a, b, result>) -> result,
return: Fold2<a, b, result>,
) -> result
Reduce a list from left to right, while accumulating two results. This is
faster (albeit equivalent) than accumulating both results in a Pair or tuple.
Using backpassing to ease readability is a good idea.
let len, sum <-
foldl2(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
0,
0,
fn(n, len, sum, return) { return(len + 1, sum + n) },
)
and {
len == 10,
sum == 55,
}
Reduce a list from right to left.
list.foldr([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldr([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [1, 2, 3]
foldr2(
self: List<elem>,
zero_a: a,
zero_b: b,
with: fn(elem, a, b, Fold2<a, b, result>) -> result,
return: Fold2<a, b, result>,
) -> result
Reduce a list from right to left, while accumulating two results. This is
faster (albeit equivalent) than accumulating both results in a Pair or tuple.
Using backpassing to ease readability is a good idea.
let len, sum <-
list.foldr2(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
0,
0,
fn(n, len, sum, return) { return(len + 1, sum + n) },
)
and {
len == 10,
sum == 55,
}
Like foldr, but also provides the position (0-based) of the elements when iterating.
let group = fn(i, x, xs) { [(i, x), ..xs] }
list.indexed_foldr(["a", "b", "c"], [], group) == [
(0, "a"),
(1, "b"),
(2, "c")
]
Reduce a list from left to right using the accumulator as left operand.
Said differently, this is foldl with callback arguments swapped.
list.reduce([#[1], #[2], #[3]], #[0], bytearray.concat) == #[0, 1, 2, 3]
list.reduce([True, False, True], False, fn(b, a) { or { b, a } }) == True
Add an element in front of the list. Sometimes useful when combined with other functions.
list.push([2, 3], 1) == [1, ..[2, 3]] == [1, 2, 3]
Construct a list of a integer from a given range.
list.range(0, 3) == [0, 1, 2, 3]
list.range(-1, 1) == [-1, 0, 1]
Construct a list filled with n copies of a value.
list.repeat("na", 3) == ["na", "na", "na"]
Determine if all elements of the list satisfy the given predicate.
An empty list always satisfies the predicate.
list.all([], fn(n) { n > 0 }) == True
list.all([1, 2, 3], fn(n) { n > 0 }) == True
list.all([1, 2, 3], fn(n) { n == 2 }) == False
Determine if at least one element of the list satisfies the given predicate.
An empty list NEVER satisfies the predicate.
list.any([], fn(n) { n > 2 }) == False
list.any([1, 2, 3], fn(n) { n > 0 }) == True
list.any([1, 2, 3], fn(n) { n == 2 }) == True
list.any([1, 2, 3], fn(n) { n < 0 }) == False
Return Some(item) at the index or None if the index is out of range. The index is 0-based.
list.at([1, 2, 3], 1) == Some(2)
list.at([1, 2, 3], 42) == None
Count how many items in the list satisfy the given predicate.
list.count([], fn(a) { a > 2}) == 0
list.count([1, 2, 3], fn(a) { n > 0 }) == 3
list.count([1, 2, 3], fn(a) { n >= 2 }) == 2
list.count([1, 2, 3], fn(a) { n > 5 }) == 0
Find the first element satisfying the given predicate, if any.
list.find([1, 2, 3], fn(x) { x == 2 }) == Some(2)
list.find([4, 5, 6], fn(x) { x == 2 }) == None
Like find, but maps the found element to something else. This
provides an efficient way to access and transform an element in a list.
expect Some(2) = list.find_map(["a", "bb", "ccc"], fn(x) {
let len = bytearray.length(x)
if len > 1 {
Some(len)
} else {
None
}
})
Figures out whether a list contain the given element.
list.has([1, 2, 3], 2) == True
list.has([1, 2, 3], 14) == False
list.has([], 14) == False
Get the first element of a list
list.head([1, 2, 3]) == Some(1)
list.head([]) == None
Checks whether a list is empty.
list.is_empty([]) == True
list.is_empty([1, 2, 3]) == False
Gets the index of an element of a list, if any. Otherwise, returns None.
list.index_of([1, 5, 2], 2) == Some(2)
list.index_of([1, 7, 3], 4) == None
list.index_of([1, 0, 9, 6], 6) == Some(3)
list.index_of([], 6) == None
Get the last in the given list, if any.
list.last([]) == None
list.last([1, 2, 3]) == Some(3)
Get the number of elements in the given list.
list.length([]) == 0
list.length([1, 2, 3]) == 3
Inspecting Forcibly
More efficient version of any, but fails if no element satisfies the predicate.
An empty list NEVER satisfies the predicate.
list.any([], fn(n) { n > 2 }) β π₯
list.any([1, 2, 3], fn(n) { n > 0 }) == True
list.any([1, 2, 3], fn(n) { n == 2 }) == True
list.any([1, 2, 3], fn(n) { n < 0 }) β π₯
More efficient version of at, but fails if thereβs no element at the
given index (or if the index is out of bound).
list.expect_at([1, 2, 3], 1) == 2
list.expect_at([1, 2, 3], 42) β π₯
More efficient version of find, but fails if the element is not found.
list.expect_find([1, 2, 3], fn(x) { x == 2 }) == 2
list.expect_find([4, 5, 6], fn(x) { x == 2 }) β π₯
More efficient version of find_map but fails if no element
is selected.
expect 2 = list.expect_find_map(["a", "bb", "ccc"], fn(x, keep, discard) {
let len = bytearray.length(x)
if len > 1 {
keep(len)
} else {
discard()
}
})
More efficient version of has but fails if the element is missing.
list.expect_has([1, 2, 3], 2) β β
list.expect_has([1, 2, 3], 14) β π₯
list.expect_has([], 14) β π₯
More efficient version of head, but fails if the list is empty.
list.expect_head([1, 2, 3]) == 1
list.expect_head([]) β π₯
More efficient version of index_of, but fails if the element
is not in the list.
list.expect_index_of([1, 5, 2], 2) == 2
list.expect_index_of([1, 7, 3], 4) β π₯
list.expect_index_of([1, 0, 9, 6], 6) == 3
list.expect_index_of([], 6) β π₯
More efficient version of last, but fails when the list is empty.
list.expect_last([1, 2, 3]) == 3
list.expect_last([]) β π₯
Modifying
Extracting
Remove the first occurrence of the given element from the list.
list.delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.delete([1, 2, 3], 14) == [1, 2, 3]
Drop the first n elements of a list.
list.drop([1, 2, 3], 2) == [3]
list.drop([], 42) == []
list.drop([1, 2, 3], 42) == []
Returns the suffix of the given list after removing all elements that satisfy the predicate.
list.drop_while([1, 2, 3], fn(x) { x < 2 }) == [2, 3]
list.drop_while([], fn(x) { x > 2 }) == []
list.drop_while([1, 2, 3], fn(x) { x == 3 }) == [1, 2, 3]
Produce a list of elements that satisfy a predicate.
list.filter([1, 2, 3], fn(x) { x >= 2 }) == [2, 3]
list.filter([], fn(x) { x > 2 }) == []
list.filter([1, 2, 3], fn(x) { x == 3 }) == [3]
Produce a list of transformed elements that satisfy a predicate.
let transform = fn(x) { if x % 2 == 0 { None } else { Some(3*x) } }
list.filter_map([1, 2, 3], transform) == [3, 9]
Return all elements except the last one.
list.init([]) == None
list.init([1, 2, 3]) == Some([1, 2])
Returns a tuple with all elements that satisfy the predicate at first
element, and the rest as second element.
list.partition([1, 2, 3, 4], fn(x) { x % 2 == 0 }) == ([2, 4], [1, 3])
Extract a sublist from the given list using 0-based indexes. Negative
indexes wrap over, so -1 refers to the last element of the list.
list.slice([1, 2, 3, 4, 5, 6], from: 2, to: 4) == [3, 4, 5]
list.slice([1, 2, 3, 4, 5, 6], from: -2, to: -1) == [5, 6]
list.slice([1, 2, 3, 4, 5, 6], from: 1, to: -1) == [2, 3, 4, 5, 6]
Cut a list in two, such that the first list contains the given number of /
elements and the second list contains the rest.
Fundamentally equivalent to (but more efficient):
// span(xs, n) == (take(xs, n), drop(xs, n))
span([1, 2, 3, 4, 5], 3) == ([1, 2, 3], [4, 5])
Get elements of a list after the first one, if any.
list.tail([]) == None
list.tail([1, 2, 3]) == Some([2, 3])
Get the first n elements of a list.
list.take([1, 2, 3], 2) == [1, 2]
list.take([1, 2, 3], 14) == [1, 2, 3]
Returns the longest prefix of the given list where all elements satisfy the predicate.
list.take_while([1, 2, 3], fn(x) { x > 2 }) == []
list.take_while([1, 2, 3], fn(x) { x < 2 }) == [1]
Removes duplicate elements from a list.
list.unique([1, 2, 3, 1]) == [1, 2, 3]
Extracting Forcibly
More efficient version of delete, which also fails when the element is NOT in the list.
list.expect_delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.expect_delete([1, 2, 3], 14) β π₯
More efficient version of drop, which fails when thereβs less than n elements in the list.
Yields the list when n is negative.
More efficient version of init, which fails when the list is empty.
More efficient version of tail, which fails when the list is empty.
More efficient version of take, which fails when the list contains less element than wanted.
Yields an empty list when n is negative.
Mapping
More efficient
Map elements of a list into a new list and flatten the result.
list.flat_map([1, 2, 3], fn(a) { [a, 2*a] }) == [1, 2, 2, 4, 3, 6]
Perform an action for each element of a list.
list.for_each(labels, do: fn(lbl) { trace lbl Void })
List map but provides the position (0-based) of the elements while iterating.
list.indexed_map([1, 2, 3], fn(i, x) { i + x }) == [1, 3, 5]
Apply a function to each element of a list.
list.map([1, 2, 3, 4], fn(n) { n + 1 }) == [2, 3, 4, 5]
Apply a function of two arguments, combining elements from two lists.
If one list is longer, the extra elements are dropped.
list.map2([1, 2, 3], [1, 2], fn(a, b) { a + b }) == [2, 4]
Apply a function of three arguments, combining elements from three lists.
If one list is longer, the extra elements are dropped.
list.map3([1, 2, 3], [1, 2], [1, 2, 3], fn(a, b, c) { a + b + c }) == [3, 6]
Return the list with its elements in the reserve order.
list.reverse([1, 2, 3]) == [3, 2, 1]
Sort a list in ascending order using the given comparison function.
use aiken/primitive/int
list.sort([3, 1, 4, 0, 2], int.compare) == [0, 1, 2, 3, 4]
list.sort([1, 2, 3], int.compare) == [1, 2, 3]
Decompose a list of tuples into a tuple of lists.
list.unzip([(1, "a"), (2, "b")]) == ([1, 2], ["a", "b"])
Combining
Merge two lists together.
list.concat([], []) == []
list.concat([], [1, 2, 3]) == [1, 2, 3]
list.concat([1, 2, 3], [4, 5, 6]) == [1, 2, 3, 4, 5, 6]
Remove the first occurrence of each element of the second list from the first one.
list.difference(["h", "e", "l", "l", "o"], ["l", "e", "l"]) == ["h", "o"]
list.difference([1, 2, 3, 4, 5], [1, 1, 2]) == [3, 4, 5]
list.difference([1, 2, 3], []) == [1, 2, 3]
Combine two lists together.
If one list is longer, the extra elements are dropped.
list.zip([1, 2], ["a", "b", "c"]) == [(1, "a"), (2, "b")]
Transforming
Reduce a list from left to right.
list.foldl([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldl([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [3, 2, 1]
foldl2(
self: List<elem>,
zero_a: a,
zero_b: b,
with: fn(elem, a, b, Fold2<a, b, result>) -> result,
return: Fold2<a, b, result>,
) -> result
Reduce a list from left to right, while accumulating two results. This is
faster (albeit equivalent) than accumulating both results in a Pair or tuple.
Using backpassing to ease readability is a good idea.
let len, sum <-
foldl2(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
0,
0,
fn(n, len, sum, return) { return(len + 1, sum + n) },
)
and {
len == 10,
sum == 55,
}
Reduce a list from right to left.
list.foldr([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldr([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [1, 2, 3]
foldr2(
self: List<elem>,
zero_a: a,
zero_b: b,
with: fn(elem, a, b, Fold2<a, b, result>) -> result,
return: Fold2<a, b, result>,
) -> result
Reduce a list from right to left, while accumulating two results. This is
faster (albeit equivalent) than accumulating both results in a Pair or tuple.
Using backpassing to ease readability is a good idea.
let len, sum <-
list.foldr2(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
0,
0,
fn(n, len, sum, return) { return(len + 1, sum + n) },
)
and {
len == 10,
sum == 55,
}
Like foldr, but also provides the position (0-based) of the elements when iterating.
let group = fn(i, x, xs) { [(i, x), ..xs] }
list.indexed_foldr(["a", "b", "c"], [], group) == [
(0, "a"),
(1, "b"),
(2, "c")
]
Reduce a list from left to right using the accumulator as left operand.
Said differently, this is foldl with callback arguments swapped.
list.reduce([#[1], #[2], #[3]], #[0], bytearray.concat) == #[0, 1, 2, 3]
list.reduce([True, False, True], False, fn(b, a) { or { b, a } }) == True
More efficient version of any, but fails if no element satisfies the predicate.
An empty list NEVER satisfies the predicate.
list.any([], fn(n) { n > 2 }) β π₯
list.any([1, 2, 3], fn(n) { n > 0 }) == True
list.any([1, 2, 3], fn(n) { n == 2 }) == True
list.any([1, 2, 3], fn(n) { n < 0 }) β π₯
More efficient version of at, but fails if thereβs no element at the
given index (or if the index is out of bound).
list.expect_at([1, 2, 3], 1) == 2
list.expect_at([1, 2, 3], 42) β π₯
More efficient version of find, but fails if the element is not found.
list.expect_find([1, 2, 3], fn(x) { x == 2 }) == 2
list.expect_find([4, 5, 6], fn(x) { x == 2 }) β π₯
More efficient version of find_map but fails if no element
is selected.
expect 2 = list.expect_find_map(["a", "bb", "ccc"], fn(x, keep, discard) {
let len = bytearray.length(x)
if len > 1 {
keep(len)
} else {
discard()
}
})
More efficient version of has but fails if the element is missing.
list.expect_has([1, 2, 3], 2) β β
list.expect_has([1, 2, 3], 14) β π₯
list.expect_has([], 14) β π₯
More efficient version of head, but fails if the list is empty.
list.expect_head([1, 2, 3]) == 1
list.expect_head([]) β π₯
More efficient version of index_of, but fails if the element
is not in the list.
list.expect_index_of([1, 5, 2], 2) == 2
list.expect_index_of([1, 7, 3], 4) β π₯
list.expect_index_of([1, 0, 9, 6], 6) == 3
list.expect_index_of([], 6) β π₯
More efficient version of last, but fails when the list is empty.
list.expect_last([1, 2, 3]) == 3
list.expect_last([]) β π₯
Extracting
Remove the first occurrence of the given element from the list.
list.delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.delete([1, 2, 3], 14) == [1, 2, 3]
Drop the first n elements of a list.
list.drop([1, 2, 3], 2) == [3]
list.drop([], 42) == []
list.drop([1, 2, 3], 42) == []
Returns the suffix of the given list after removing all elements that satisfy the predicate.
list.drop_while([1, 2, 3], fn(x) { x < 2 }) == [2, 3]
list.drop_while([], fn(x) { x > 2 }) == []
list.drop_while([1, 2, 3], fn(x) { x == 3 }) == [1, 2, 3]
Produce a list of elements that satisfy a predicate.
list.filter([1, 2, 3], fn(x) { x >= 2 }) == [2, 3]
list.filter([], fn(x) { x > 2 }) == []
list.filter([1, 2, 3], fn(x) { x == 3 }) == [3]
Produce a list of transformed elements that satisfy a predicate.
let transform = fn(x) { if x % 2 == 0 { None } else { Some(3*x) } }
list.filter_map([1, 2, 3], transform) == [3, 9]
Return all elements except the last one.
list.init([]) == None
list.init([1, 2, 3]) == Some([1, 2])
Returns a tuple with all elements that satisfy the predicate at first
element, and the rest as second element.
list.partition([1, 2, 3, 4], fn(x) { x % 2 == 0 }) == ([2, 4], [1, 3])
Extract a sublist from the given list using 0-based indexes. Negative
indexes wrap over, so -1 refers to the last element of the list.
list.slice([1, 2, 3, 4, 5, 6], from: 2, to: 4) == [3, 4, 5]
list.slice([1, 2, 3, 4, 5, 6], from: -2, to: -1) == [5, 6]
list.slice([1, 2, 3, 4, 5, 6], from: 1, to: -1) == [2, 3, 4, 5, 6]
Cut a list in two, such that the first list contains the given number of /
elements and the second list contains the rest.
Fundamentally equivalent to (but more efficient):
// span(xs, n) == (take(xs, n), drop(xs, n))
span([1, 2, 3, 4, 5], 3) == ([1, 2, 3], [4, 5])
Get elements of a list after the first one, if any.
list.tail([]) == None
list.tail([1, 2, 3]) == Some([2, 3])
Get the first n elements of a list.
list.take([1, 2, 3], 2) == [1, 2]
list.take([1, 2, 3], 14) == [1, 2, 3]
Returns the longest prefix of the given list where all elements satisfy the predicate.
list.take_while([1, 2, 3], fn(x) { x > 2 }) == []
list.take_while([1, 2, 3], fn(x) { x < 2 }) == [1]
Removes duplicate elements from a list.
list.unique([1, 2, 3, 1]) == [1, 2, 3]
Extracting Forcibly
More efficient version of delete, which also fails when the element is NOT in the list.
list.expect_delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.expect_delete([1, 2, 3], 14) β π₯
More efficient version of drop, which fails when thereβs less than n elements in the list.
Yields the list when n is negative.
More efficient version of init, which fails when the list is empty.
More efficient version of tail, which fails when the list is empty.
More efficient version of take, which fails when the list contains less element than wanted.
Yields an empty list when n is negative.
Mapping
More efficient
Map elements of a list into a new list and flatten the result.
list.flat_map([1, 2, 3], fn(a) { [a, 2*a] }) == [1, 2, 2, 4, 3, 6]
Perform an action for each element of a list.
list.for_each(labels, do: fn(lbl) { trace lbl Void })
List map but provides the position (0-based) of the elements while iterating.
list.indexed_map([1, 2, 3], fn(i, x) { i + x }) == [1, 3, 5]
Apply a function to each element of a list.
list.map([1, 2, 3, 4], fn(n) { n + 1 }) == [2, 3, 4, 5]
Apply a function of two arguments, combining elements from two lists.
If one list is longer, the extra elements are dropped.
list.map2([1, 2, 3], [1, 2], fn(a, b) { a + b }) == [2, 4]
Apply a function of three arguments, combining elements from three lists.
If one list is longer, the extra elements are dropped.
list.map3([1, 2, 3], [1, 2], [1, 2, 3], fn(a, b, c) { a + b + c }) == [3, 6]
Return the list with its elements in the reserve order.
list.reverse([1, 2, 3]) == [3, 2, 1]
Sort a list in ascending order using the given comparison function.
use aiken/primitive/int
list.sort([3, 1, 4, 0, 2], int.compare) == [0, 1, 2, 3, 4]
list.sort([1, 2, 3], int.compare) == [1, 2, 3]
Decompose a list of tuples into a tuple of lists.
list.unzip([(1, "a"), (2, "b")]) == ([1, 2], ["a", "b"])
Combining
Merge two lists together.
list.concat([], []) == []
list.concat([], [1, 2, 3]) == [1, 2, 3]
list.concat([1, 2, 3], [4, 5, 6]) == [1, 2, 3, 4, 5, 6]
Remove the first occurrence of each element of the second list from the first one.
list.difference(["h", "e", "l", "l", "o"], ["l", "e", "l"]) == ["h", "o"]
list.difference([1, 2, 3, 4, 5], [1, 1, 2]) == [3, 4, 5]
list.difference([1, 2, 3], []) == [1, 2, 3]
Combine two lists together.
If one list is longer, the extra elements are dropped.
list.zip([1, 2], ["a", "b", "c"]) == [(1, "a"), (2, "b")]
Transforming
Reduce a list from left to right.
list.foldl([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldl([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [3, 2, 1]
foldl2(
self: List<elem>,
zero_a: a,
zero_b: b,
with: fn(elem, a, b, Fold2<a, b, result>) -> result,
return: Fold2<a, b, result>,
) -> result
Reduce a list from left to right, while accumulating two results. This is
faster (albeit equivalent) than accumulating both results in a Pair or tuple.
Using backpassing to ease readability is a good idea.
let len, sum <-
foldl2(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
0,
0,
fn(n, len, sum, return) { return(len + 1, sum + n) },
)
and {
len == 10,
sum == 55,
}
Reduce a list from right to left.
list.foldr([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldr([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [1, 2, 3]
foldr2(
self: List<elem>,
zero_a: a,
zero_b: b,
with: fn(elem, a, b, Fold2<a, b, result>) -> result,
return: Fold2<a, b, result>,
) -> result
Reduce a list from right to left, while accumulating two results. This is
faster (albeit equivalent) than accumulating both results in a Pair or tuple.
Using backpassing to ease readability is a good idea.
let len, sum <-
list.foldr2(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
0,
0,
fn(n, len, sum, return) { return(len + 1, sum + n) },
)
and {
len == 10,
sum == 55,
}
Like foldr, but also provides the position (0-based) of the elements when iterating.
let group = fn(i, x, xs) { [(i, x), ..xs] }
list.indexed_foldr(["a", "b", "c"], [], group) == [
(0, "a"),
(1, "b"),
(2, "c")
]
Reduce a list from left to right using the accumulator as left operand.
Said differently, this is foldl with callback arguments swapped.
list.reduce([#[1], #[2], #[3]], #[0], bytearray.concat) == #[0, 1, 2, 3]
list.reduce([True, False, True], False, fn(b, a) { or { b, a } }) == True
Remove the first occurrence of the given element from the list.
list.delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.delete([1, 2, 3], 14) == [1, 2, 3]
Drop the first n elements of a list.
list.drop([1, 2, 3], 2) == [3]
list.drop([], 42) == []
list.drop([1, 2, 3], 42) == []
Returns the suffix of the given list after removing all elements that satisfy the predicate.
list.drop_while([1, 2, 3], fn(x) { x < 2 }) == [2, 3]
list.drop_while([], fn(x) { x > 2 }) == []
list.drop_while([1, 2, 3], fn(x) { x == 3 }) == [1, 2, 3]
Produce a list of elements that satisfy a predicate.
list.filter([1, 2, 3], fn(x) { x >= 2 }) == [2, 3]
list.filter([], fn(x) { x > 2 }) == []
list.filter([1, 2, 3], fn(x) { x == 3 }) == [3]
Produce a list of transformed elements that satisfy a predicate.
let transform = fn(x) { if x % 2 == 0 { None } else { Some(3*x) } }
list.filter_map([1, 2, 3], transform) == [3, 9]
Return all elements except the last one.
list.init([]) == None
list.init([1, 2, 3]) == Some([1, 2])
Returns a tuple with all elements that satisfy the predicate at first element, and the rest as second element.
list.partition([1, 2, 3, 4], fn(x) { x % 2 == 0 }) == ([2, 4], [1, 3])
Extract a sublist from the given list using 0-based indexes. Negative
indexes wrap over, so -1 refers to the last element of the list.
list.slice([1, 2, 3, 4, 5, 6], from: 2, to: 4) == [3, 4, 5]
list.slice([1, 2, 3, 4, 5, 6], from: -2, to: -1) == [5, 6]
list.slice([1, 2, 3, 4, 5, 6], from: 1, to: -1) == [2, 3, 4, 5, 6]
Cut a list in two, such that the first list contains the given number of / elements and the second list contains the rest.
Fundamentally equivalent to (but more efficient):
// span(xs, n) == (take(xs, n), drop(xs, n))
span([1, 2, 3, 4, 5], 3) == ([1, 2, 3], [4, 5])
Get elements of a list after the first one, if any.
list.tail([]) == None
list.tail([1, 2, 3]) == Some([2, 3])
Get the first n elements of a list.
list.take([1, 2, 3], 2) == [1, 2]
list.take([1, 2, 3], 14) == [1, 2, 3]
Returns the longest prefix of the given list where all elements satisfy the predicate.
list.take_while([1, 2, 3], fn(x) { x > 2 }) == []
list.take_while([1, 2, 3], fn(x) { x < 2 }) == [1]
Removes duplicate elements from a list.
list.unique([1, 2, 3, 1]) == [1, 2, 3]
More efficient version of delete, which also fails when the element is NOT in the list.
list.expect_delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.expect_delete([1, 2, 3], 14) β π₯
More efficient version of drop, which fails when thereβs less than n elements in the list.
Yields the list when n is negative.
More efficient version of init, which fails when the list is empty.
More efficient version of tail, which fails when the list is empty.
More efficient version of take, which fails when the list contains less element than wanted.
Yields an empty list when n is negative.
Mapping
More efficient
Map elements of a list into a new list and flatten the result.
list.flat_map([1, 2, 3], fn(a) { [a, 2*a] }) == [1, 2, 2, 4, 3, 6]
Perform an action for each element of a list.
list.for_each(labels, do: fn(lbl) { trace lbl Void })
List map but provides the position (0-based) of the elements while iterating.
list.indexed_map([1, 2, 3], fn(i, x) { i + x }) == [1, 3, 5]
Apply a function to each element of a list.
list.map([1, 2, 3, 4], fn(n) { n + 1 }) == [2, 3, 4, 5]
Apply a function of two arguments, combining elements from two lists.
If one list is longer, the extra elements are dropped.
list.map2([1, 2, 3], [1, 2], fn(a, b) { a + b }) == [2, 4]
Apply a function of three arguments, combining elements from three lists.
If one list is longer, the extra elements are dropped.
list.map3([1, 2, 3], [1, 2], [1, 2, 3], fn(a, b, c) { a + b + c }) == [3, 6]
Return the list with its elements in the reserve order.
list.reverse([1, 2, 3]) == [3, 2, 1]
Sort a list in ascending order using the given comparison function.
use aiken/primitive/int
list.sort([3, 1, 4, 0, 2], int.compare) == [0, 1, 2, 3, 4]
list.sort([1, 2, 3], int.compare) == [1, 2, 3]
Decompose a list of tuples into a tuple of lists.
list.unzip([(1, "a"), (2, "b")]) == ([1, 2], ["a", "b"])
Combining
More efficient Map elements of a list into a new list and flatten the result.
list.flat_map([1, 2, 3], fn(a) { [a, 2*a] }) == [1, 2, 2, 4, 3, 6]
Perform an action for each element of a list.
list.for_each(labels, do: fn(lbl) { trace lbl Void })
List map but provides the position (0-based) of the elements while iterating.
list.indexed_map([1, 2, 3], fn(i, x) { i + x }) == [1, 3, 5]
Apply a function to each element of a list.
list.map([1, 2, 3, 4], fn(n) { n + 1 }) == [2, 3, 4, 5]
Apply a function of two arguments, combining elements from two lists.
If one list is longer, the extra elements are dropped.
list.map2([1, 2, 3], [1, 2], fn(a, b) { a + b }) == [2, 4]
Apply a function of three arguments, combining elements from three lists.
If one list is longer, the extra elements are dropped.
list.map3([1, 2, 3], [1, 2], [1, 2, 3], fn(a, b, c) { a + b + c }) == [3, 6]
Return the list with its elements in the reserve order.
list.reverse([1, 2, 3]) == [3, 2, 1]
Sort a list in ascending order using the given comparison function.
use aiken/primitive/int
list.sort([3, 1, 4, 0, 2], int.compare) == [0, 1, 2, 3, 4]
list.sort([1, 2, 3], int.compare) == [1, 2, 3]
Decompose a list of tuples into a tuple of lists.
list.unzip([(1, "a"), (2, "b")]) == ([1, 2], ["a", "b"])
Merge two lists together.
list.concat([], []) == []
list.concat([], [1, 2, 3]) == [1, 2, 3]
list.concat([1, 2, 3], [4, 5, 6]) == [1, 2, 3, 4, 5, 6]
Remove the first occurrence of each element of the second list from the first one.
list.difference(["h", "e", "l", "l", "o"], ["l", "e", "l"]) == ["h", "o"]
list.difference([1, 2, 3, 4, 5], [1, 1, 2]) == [3, 4, 5]
list.difference([1, 2, 3], []) == [1, 2, 3]
Combine two lists together.
If one list is longer, the extra elements are dropped.
list.zip([1, 2], ["a", "b", "c"]) == [(1, "a"), (2, "b")]
Transforming
Reduce a list from left to right.
list.foldl([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldl([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [3, 2, 1]
foldl2(
self: List<elem>,
zero_a: a,
zero_b: b,
with: fn(elem, a, b, Fold2<a, b, result>) -> result,
return: Fold2<a, b, result>,
) -> result
Reduce a list from left to right, while accumulating two results. This is
faster (albeit equivalent) than accumulating both results in a Pair or tuple.
Using
backpassingto ease readability is a good idea.
let len, sum <-
foldl2(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
0,
0,
fn(n, len, sum, return) { return(len + 1, sum + n) },
)
and {
len == 10,
sum == 55,
}
Reduce a list from right to left.
list.foldr([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldr([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [1, 2, 3]
foldr2(
self: List<elem>,
zero_a: a,
zero_b: b,
with: fn(elem, a, b, Fold2<a, b, result>) -> result,
return: Fold2<a, b, result>,
) -> result
Reduce a list from right to left, while accumulating two results. This is
faster (albeit equivalent) than accumulating both results in a Pair or tuple.
Using
backpassingto ease readability is a good idea.
let len, sum <-
list.foldr2(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
0,
0,
fn(n, len, sum, return) { return(len + 1, sum + n) },
)
and {
len == 10,
sum == 55,
}
Like foldr, but also provides the position (0-based) of the elements when iterating.
let group = fn(i, x, xs) { [(i, x), ..xs] }
list.indexed_foldr(["a", "b", "c"], [], group) == [
(0, "a"),
(1, "b"),
(2, "c")
]
Reduce a list from left to right using the accumulator as left operand.
Said differently, this is foldl with callback arguments swapped.
list.reduce([#[1], #[2], #[3]], #[0], bytearray.concat) == #[0, 1, 2, 3]
list.reduce([True, False, True], False, fn(b, a) { or { b, a } }) == True