Antra

Standardbibliothek

Antra::Array

import Antra::Array

Array operations for Antra.

Antra::Array combines immutable vector operations with mutable array mutations.

Mutable Operations: Functions like push, pop, shift, unshift work in-place on mutable array values and return the mutated array.

Immutable Operations (Vector-style): Functions like length, head, tail, sort, join, flatten, etc. treat arrays as immutable values and return new arrays or scalar results.

Sequence Helpers (Enum-style): Traversal functions like map, filter, reduce, each, find, zip, take_while, drop_while are re-exported from Antra::Enum.

Überblick#

Fuer klassische Array-Operationen:

  • length
  • sum
  • product
  • min, max
  • reverse
  • any, all
  • reduce
  • take, drop, zip
  • flatten - eine Ebene; depth: n mehrere, depth: :all vollständig
  • flat_map - map und eine Ebene glätten
  • put(xs, i, v) - neues Array mit ersetztem Element (xs bleibt, wie es ist)
  • sort_by, min_by, max_by, group_by - nach einer Schlüsselfunktion
import Antra::Array

val words = ["pear", "fig", "banana", "kiwi"]
println(Array.sort_by(words, &len))             # ['fig', 'pear', 'kiwi', 'banana']
println(Array.max_by(words, &len))              # banana
println(Array.group_by(words, &len)[4])         # ['pear', 'kiwi']

sort_by ist stabil (gleiche Schlüssel behalten ihre Reihenfolge), min_by und max_by liefern bei Gleichstand das erste Element und für [] undef.

Antra::Array ist dabei bewusst array-zentriert. Die Sequenz-Helfer (map, filter, reduce, find, count, zip, take_while, …) sind dieselben Funktionen wie in Antra::Enum, aber mit Array-Signaturen und eigener Doku: Sie nehmen nur Arrays, ein Callback darf den Index als zweiten Parameter nehmen (fn(T, ?Int) -> U):

import Antra::Array

println(Array.map([10, 20], |x, i| -> x + i))   # [10, 21]
println(Array.count([1, 2, 3], \_ > 1))          # 2
# Array.map(1..3, \_ * 2)                        # --check: expected [_], found Range

Wenn du mit allgemeinen Sequences wie Ranges, Strings, Maps oder gen fn-Generatoren arbeiten willst, nimm dafuer foreach(...), map(...), filter(...), take(...), collect(...) oder das Paket Antra::Enum. Im REPL zeigt :doc Array.map Signatur und Beispiele.

Mutierende Array-Operationen#

Fuer kleine explizit mutierende Operationen auf normalen Arrays nutze auch Antra::Array:

Antra::Array bietet Mutations-Helfer:

  • Array.push(mut xs, value) haengt hinten an und gibt das mutierte Array zurueck
  • Array.pop(mut xs) entfernt das letzte Element und gibt es zurueck
  • Array.shift(mut xs) entfernt das erste Element und gibt es zurueck
  • Array.unshift(mut xs, value) fuegt vorne ein und gibt das mutierte Array zurueck

Die erste Version arbeitet bewusst nur auf normalen Arrays, nicht auf Tagged Arrays.

import Antra::Array as Array

my xs = [2, 3]
Array.unshift(xs, 1)
println(xs)
println(Array.pop(xs))
println(xs)

Mutierend#

Antra::Array ist die API fuer materialisierte Arrays. Das Modul ist die Anlaufstelle fuer array-spezifische Helfer und shape-orientierte Operationen.

import Antra::Array as A

A.length(list)
A.sum(list)
A.product(list)
A.min(list)
A.min(list).!
A.max(list)
A.max(list).!
L.reverse(list)
L.take(n, list)
L.drop(n, list)
L.head(list)
L.tail(list)
L.last(list)
L.init(list)
L.append(list, value)
L.prepend(list, value)
L.join(list, sep)
L.chunk_every(list, n)

Sequence-orientierte Traversals wie map, reduce, any, all, find, zip, take_while oder drop_while liegen bewusst bei Antra::Enum.

Kurz gesagt:

  • List beschreibt die Form eines vorhandenen Arrays
  • Enum beschreibt das Durchlaufen einer allgemeinen Sequence

Referenz#

import Antra::Array as A

A.push(array, value)
A.pop(array)
A.pop(array).!
A.shift(array)
A.shift(array).!
A.unshift(array, value)
A.clear(array)
A.insert(array, index, value)
A.insert(array, index, value).!
A.remove_at(array, index)
A.remove_at(array, index).!

Alle diese Funktionen sind explizit mutierend. Ohne ! liefern die potenziell fehlschlagenden Varianten ein Result; mit ! werfen sie bei ungueltigen Zustaenden oder Indizes.

Funktionen#

fn all(array :- [T], pred :- fn(T, ?Int) -> Bool) :- Bool

Whether pred holds for every element (stops at the first that does not); true for an empty array.

Array.all([2, 4], \_ % 2 == 0)   # => true
fn any(array :- [T], pred :- fn(T, ?Int) -> Bool) :- Bool

Whether pred holds for some element (stops at the first).

Array.any([1, 5, 2], \_ > 4)   # => true
fn append(array :- [T], value :- T) :- [T]

Returns a new array with value appended at the end.

Example:

Array.append([1, 2], 3)   # => [1, 2, 3]
fn chunk(array :- [T], n :- Int) :- [[T]]

Splits into arrays of n elements; the last may be shorter.

Array.chunk([1, 2, 3, 4, 5], 2)   # => [[1, 2], [3, 4], [5]]
fn chunk_every(array, n)
fn chunk_every(array, n, step)

Splits an array into chunks of size n.

Example:

Array.chunk_every([1, 2, 3, 4, 5], 2)   # => [[1, 2], [3, 4], [5]]
fn clear(mut array :- [T]) :- [T]

Removes all elements and returns the mutated array.

Example:

my xs = [1, 2, 3]
Array.clear(xs)   # => []
fn concat(..vecs :- ..[T]) :- [T]

Concatenates multiple arrays into a single array.

Example:

Array.concat([1, 2], [3], [4, 5])   # => [1, 2, 3, 4, 5]
fn count(array :- [T]) :- Int
fn count(array :- [T], pred :- fn(T, ?Int) -> Bool) :- Int

The number of elements, or of those for which pred holds.

Array.count([1, 2, 3])               # => 3
Array.count([1, 2, 3], \_ % 2 == 1)  # => 2
fn drop(array :- [T], n :- Number) :- [T]

Returns the array without its first n elements.

Example:

Array.drop([1, 2, 3, 4], 2)   # => [3, 4]
fn drop_while(array :- [T], pred :- fn(T, ?Int) -> Bool) :- [T]

The elements after the leading ones for which pred holds.

Array.drop_while([1, 2, 5, 1], \_ < 3)   # => [5, 1]
fn each(array :- [T], f :- fn(T, ?Int) -> U)

Calls f on every element for its effect (|x, i|: with the index); returns the last result. last/next in f stop or skip.

Array.each(["a", "b"], |x, i| -> println(i, ": ", x))
fn empty?(array :- [T]) :- Bool

Whether the array has no elements.

Array.empty?([])   # => true
fn filter(array :- [T], pred :- fn(T, ?Int) -> Bool) :- [T]

Keeps the elements for which pred holds (|x, i|: with the index).

Array.filter([1, 2, 3, 4], \_ % 2 == 0)   # => [2, 4]
fn find(array :- [T], pred :- fn(T, ?Int) -> Bool) :- Option[T]

The first element for which pred holds.

Array.find([1, 5, 7], \_ > 4)   # => %Some[5]
Array.find([1, 2], \_ > 4)      # => %None[]
fn find_index(array :- [T], pred :- fn(T, ?Int) -> Bool) :- Option[Int]

The index of the first element for which pred holds.

Array.find_index(["a", "b"], \_ == "b")   # => %Some[1]
fn find_map(array :- [T], f :- fn(T, ?Int) -> Option[U]) :- Option[U]

The first %Some[...] that f gives (f returns an Option).

Array.find_map(["x", "42"], |s| -> if s =~ regex"^\d+$" then %Some[num(s)] else %None[])   # => %Some[42]
fn flat_map(array :- [T], f :- fn(T, ?Int) -> [U]) :- [U]

Maps every element to an array and joins them, one level.

Array.flat_map([1, 2], |x| -> [x, x * 10])   # => [1, 10, 2, 20]
fn flatten(array, [depth: = 1])

Flattens nested arrays by one level, or depth: levels; depth: :all flattens completely. Tagged arrays (%Pair[...]) stay elements.

Example:

Array.flatten([1, [2, [3]], 4])               # => [1, 2, [3], 4]
Array.flatten([1, [2, [3]], 4], depth: :all)  # => [1, 2, 3, 4]
fn fold_left(array :- [T], acc :- A, f :- fn(A, T, ?Int) -> A) :- A

The same as reduce, with the accumulator-first name.

Array.fold_left(["a", "b"], "", |acc, s| -> acc <> s)   # => "ab"
fn fold_right(array :- [T], acc :- A, f :- fn(T, A) -> A) :- A

Folds an array from the right.

Example:

Array.fold_right([1, 2, 3], 0, |x, acc| -> x + acc)   # => 6
fn group_by(array :- [T], key :- fn(T) -> Any) :- Map[String, [T]]

Map from key to the elements with that key, in their original order.

Example:

Array.group_by(["fig", "kiwi", "pear"], &len)   # => %{3 => ["fig"], 4 => ["kiwi", "pear"]}
fn head!(array :- [T]) :- T

Returns the first element or raises a runtime error for an empty array.

Example:

Array.head!([1, 2, 3])   # => 1
fn index_map(array :- [T], fn :- fn(T, Number) -> U) :- [U]

Maps fn(elem, index) over an array.

Example:

Array.index_map([10, 20, 30], |x, i| -> x + i)   # => [10, 21, 32]
fn init(array :- [T]) :- Option[[T]]

Returns %Some[rest] without the last element, or %None[].

Example:

Array.init([1, 2, 3])   # => %Some[[1, 2]]
Array.init([])          # => %None[]
fn init!(array :- [T]) :- [T]

Returns all elements except the last one, or raises a runtime error for an empty array.

Example:

Array.init!([1, 2, 3])   # => [1, 2]
fn insert(mut array :- [T], index :- Number, value :- T) :- Result[[T], Any]

Inserts value at index and returns %Ok[array], or %Err["..."] if the index is invalid.

Example:

my xs = [1, 3]
Array.insert(xs, 1, 2)   # => %Ok[[1, 2, 3]]
fn is_empty(array :- [T]) :- Bool

Returns true if the array has no elements.

Example:

Array.is_empty([])        # => true
Array.is_empty([1, 2])    # => false
fn join(array :- [Any], sep :- String) :- String

Joins an array of values with sep.

Example:

Array.join(["a", "b", "c"], ",")   # => "a,b,c"
fn last(array :- [T]) :- Option[T]

Returns %Some[x] for the last element, or %None[].

Example:

Array.last([1, 2, 3])   # => %Some[3]
Array.last([])          # => %None[]
fn last!(array :- [T]) :- T

Returns the last element or raises a runtime error for an empty array.

Example:

Array.last!([1, 2, 3])   # => 3
fn length(array :- [T]) :- Number

Returns the number of elements in an array.

Example:

Array.length([1, 2, 3])   # => 3
fn map(array :- [T], f :- fn(T, ?Int) -> U) :- [U]

Applies f to every element (|x, i|: with the index).

Array.map([1, 2, 3], \_ * 10)   # => [10, 20, 30]
fn max(array :- [T]) :- Result[T, Any]

Returns %Ok[max] for the largest element or %Err["..."] for an empty array.

Example:

Array.max([3, 1, 4])   # => %Ok[4]
fn max_by(array :- [T], key :- fn(T) -> Any) :- T?

Element with the largest key (the first one on ties); undef for [].

fn member?(array :- [T], value) :- Bool

Whether value is an element (==).

Array.member?([1, 2, 3], 2)   # => true
fn min(array :- [T]) :- Result[T, Any]

Returns %Ok[min] for the smallest element or %Err["..."] for an empty array.

Example:

Array.min([3, 1, 4])   # => %Ok[1]
fn min_by(array :- [T], key :- fn(T) -> Any) :- T?

Element with the smallest key (the first one on ties); undef for [].

fn partition(array :- [T], pred :- fn(T) -> Any) :- [[T]]

Splits an array into [matching, rest] based on pred.

Example:

Array.partition([1, 2, 3, 4], |x| -> x % 2 == 0)   # => [[2, 4], [1, 3]]
fn pop(mut array :- [T]) :- Result[T, String]

Removes and returns %Ok[value], or %Err["empty array"] for an empty array.

Example:

my xs = [1, 2, 3]
Array.pop(xs)   # => %Ok[3]
fn prepend(array :- [T], value :- T) :- [T]

Returns a new array with value prepended at the start.

Example:

Array.prepend([2, 3], 1)   # => [1, 2, 3]
fn product(array :- [Number]) :- Number

Multiplies all elements of an array.

Example:

Array.product([2, 3, 4])   # => 24
fn push(mut array :- [T], value :- T) :- [T]

Appends value to array and returns the mutated array.

Example:

my xs = [1, 2]
Array.push(xs, 3)   # => [1, 2, 3]
fn put(array :- [T], index :- Number, value :- T) :- [T]

Returns a new array with the element at index replaced by value; the original stays as it is. A negative index counts from the end.

Example:

Array.put([1, 2, 3], 1, 9)    # => [1, 9, 3]
Array.put([1, 2, 3], -1, 0)   # => [1, 2, 0]
fn reduce(array :- [T], acc :- A, f :- fn(A, T, ?Int) -> A) :- A

Folds from the left: f(acc, x) for every element, starting with acc (|acc, x, i|: with the index).

Array.reduce([1, 2, 3], 0, |acc, x| -> acc + x)   # => 6
fn reject(array :- [T], pred :- fn(T, ?Int) -> Bool) :- [T]

Keeps the elements for which pred does not hold (|x, i|: with the index).

Array.reject([1, 2, 3, 4], \_ % 2 == 0)   # => [1, 3]
fn remove_at(mut array :- [T], index :- Number) :- Result[T, Any]

Removes and returns %Ok[value], or %Err["..."] if the index is invalid.

Example:

my xs = [10, 20, 30]
Array.remove_at(xs, 1)   # => %Ok[20]
fn repeat(elem :- T, n :- Number) :- [T]

Returns an array containing elem repeated n times.

Example:

Array.repeat("x", 3)   # => ["x", "x", "x"]
fn reverse(array :- [T]) :- [T]

Returns a new array with the elements in reverse order.

Example:

Array.reverse([1, 2, 3])   # => [3, 2, 1]
fn shift(mut array :- [T]) :- Result[T, String]

Removes and returns %Ok[value], or %Err["empty array"] for an empty array.

Example:

my xs = [1, 2, 3]
Array.shift(xs)   # => %Ok[1]
fn sort(array)
fn sort(array, fn)

Sorts an array in natural order (numeric if possible, otherwise lexicographic).

Example:

Array.sort([3, 1, 2])   # => [1, 2, 3]
fn sort_by(array :- [T], key :- fn(T) -> Any) :- [T]

Sorts by a key function; keys compare like <=>, equal keys keep their order (stable).

Example:

Array.sort_by(["pear", "fig", "banana"], &len)   # => ["fig", "pear", "banana"]
fn sort_natural(array :- [T]) :- [T]

Sorts an array explicitly in natural order.

Example:

Array.sort_natural(["file10", "file2", "file1"])   # => ["file1", "file2", "file10"]
fn sum(array :- [Number]) :- Number

Sums all elements of an array.

Example:

Array.sum([1, 2, 3])   # => 6
fn tail(array :- [T]) :- Option[[T]]

Returns %Some[rest] for all elements after the first, or %None[].

Example:

Array.tail([1, 2, 3])   # => %Some[[2, 3]]
Array.tail([])          # => %None[]
fn tail!(array :- [T]) :- [T]

Returns all elements after the first, or raises a runtime error for an empty array.

Example:

Array.tail!([1, 2, 3])   # => [2, 3]
fn take(array :- [T], n :- Number) :- [T]

Returns the first n elements of an array.

Example:

Array.take([1, 2, 3, 4], 2)   # => [1, 2]
fn take_while(array :- [T], pred :- fn(T, ?Int) -> Bool) :- [T]

The leading elements for which pred holds.

Array.take_while([1, 2, 5, 1], \_ < 3)   # => [1, 2]
fn to_array(seq :- Seq[T]) :- [T]

Materializes any sequence (a range, a string, a map's values, a generator) into a new array; an array is copied.

Array.to_array(1..3)   # => [1, 2, 3]
fn unique(array :- [T]) :- [T]

Returns an array with duplicates removed, preserving order.

Example:

Array.unique([1, 2, 1, 3, 2])   # => [1, 2, 3]
fn unshift(mut array :- [T], value :- T) :- [T]

Prepends value to array and returns the mutated array.

Example:

my xs = [2, 3]
Array.unshift(xs, 1)   # => [1, 2, 3]
fn zip(a :- [A], b :- [B]) :- [[A, B]]

Pairs the elements of two arrays, up to the shorter one.

Array.zip([1, 2, 3], ["a", "b"])   # => [[1, "a"], [2, "b"]]
fn zip_with(a :- [A], b :- [B], f :- fn(A, B) -> C) :- [C]

Combines the elements of two arrays with f, up to the shorter one.

Array.zip_with([1, 2], [10, 20], |a, b| -> a + b)   # => [11, 22]

Quelle dieser Seite