Standardbibliothek
Antra::Map
import Antra::MapFunctional operations for maps in Antra.
Antra::Map mostly treats maps as immutable values. Functions return new
maps or scalar results instead of mutating the given map in place, except
for explicit mutable helpers like set.
A tagged map (%Cfg{...}, a package's object) is a map with a label:
every function takes it, and the ones that return a map keep its tag; on
an object with declared fields, new keys must be fields (as obj.k = v).
Core operations delegate to Antra::Native::Map, while small compositions
are implemented directly in Antra.
Überblick#
import Antra::Map as M
M.keys(map)
M.values(map)
M.entries(map)
M.size(map)
M.has_key(map, key)
M.get(map, key)
M.get_or(map, key, default)
M.fetch(map, key)
M.merge(a, b)
M.map_values(map, f)
M.filter_entries(map, f)
M.from_entries(pairs)
M.from_entries(pairs).!
M.from_keywords(pairs)
M.from_keywords(pairs).!
M.to_keywords(map)Zusaetzlich reexportiert Antra::Map die naheliegenden Sequence-Helfer aus
Antra::Enum, damit auch Formen wie Map.to_array(...), Map.count(...),
Map.member?(...), Map.take(...), Map.drop(...) und Map.empty?(...)
unter demselben Namespace verfuegbar sind. Sie durchlaufen die Werte, wie for
(Map.to_array(m) ist Map.values(m)); ein Callback mit zwei Parametern
bekommt den Schluessel dazu. Die Paare gibt Map.entries(m).
Eine getaggte Map (%Cfg{...}, das Objekt eines Packages) ist für
Antra::Map eine Map mit Etikett: alle Funktionen nehmen sie, und die, die eine
Map liefern (set, assoc, dissoc, update, merge, map_values,
filter_entries, select_keys, *_in), behalten ihren Tag. Bei einem Objekt
mit deklarierten Feldern dürfen neue Schlüssel nur Felder sein, wie bei
obj.k = v:
import Antra::Map
package Wallet {
pub field cents = 0
}
val w = %Wallet{cents: 950}
println(Map.assoc(w, :cents, 1000)) # %Wallet{ :cents => 1000 }
println(try { Map.assoc(w, :euro, 9) } catch { e -> str(e) }) # Error: package 'Wallet' has no field 'euro'Antra::Set reexportiert ebenfalls einen sinnvollen Teil von Antra::Enum,
aber bewusst nur die nicht auf Reihenfolge angewiesenen Helfer wie
Set.count(...), Set.member?(...), Set.empty?(...), Set.any(...),
Set.all(...), Set.find(...), Set.map(...) oder Set.filter(...).
Bewusst nicht unter Set gespiegelt werden Reihenfolge-Helfer wie take,
drop oder zip, weil Sets semantisch keine geordnete Collection sind.
Funktionen#
allanyassocassoc_inchunkcountdeletedissocdissoc_indropdrop_whileeachempty?entriesfetchfilterfilter_entriesfindfind_mapflat_mapfold_leftfrom_entriesfrom_keywordsgetget_orhas_keykeysmapmap_valuesmember?mergemerge_withreducerejectselect_keyssetsizetaketake_whileto_arrayto_keywordsupdateupdate_invalueszipzip_with
fn all(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- BoolWhether pred holds for every value; true for an empty map.
Map.all(%{a: 2, b: 4}, \_ % 2 == 0) # => truefn any(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- BoolWhether pred holds for some value.
Map.any(%{a: 1, b: 5}, \_ > 4) # => truefn assoc(map :- Map[K, V], key, value)Returns a fresh map with key set to value, leaving map unchanged.
Example:
my person = %{name: "Ana"}
my updated = Map.assoc(person, :age, 42)
defined?(person.age) # => false
updated.age # => 42fn assoc_in(map :- Map[Any, Any], path :- [Any], value)Returns a fresh map with value written at the nested path.
Missing intermediate maps are created automatically.
Example:
my updated = Map.assoc_in(%{user: %{name: "Ana"}}, [:user, :age], 42)
updated.user.age # => 42fn chunk(map :- Map[K, V], n :- Int) :- [[V]]Splits the values (in key order) into arrays of n; the last may
be shorter.
Map.chunk(%{a: 1, b: 2, c: 3}, 2) # => [[1, 2], [3]]fn count(map :- Map[K, V]) :- Int
fn count(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- IntThe number of entries, or of the values for which pred holds.
Map.count(%{a: 1, b: 2}) # => 2
Map.count(%{a: 1, b: 2}, \_ > 1) # => 1fn delete(mut map :- Map[K, V], key)Mutates map in place by deleting key and returns the mutated map.
Example:
my person = %{name: "Ana", age: 42}
Map.delete(person, :age)
defined?(person.age) # => falsefn dissoc(map :- Map[K, V], key)Returns a fresh map without key, leaving map unchanged.
Example:
my updated = Map.dissoc(%{name: "Ana", age: 42}, :age)
defined?(updated.age) # => falsefn dissoc_in(map :- Map[Any, Any], path :- [Any])Returns a fresh map with the nested value at path removed.
Missing paths are ignored. Empty intermediate maps are pruned.
Example:
my updated = Map.dissoc_in(%{user: %{name: "Ana", age: 42}}, [:user, :age])
defined?(updated.user.age) # => falsefn drop(map :- Map[K, V], n :- Int) :- [V]The values after the first n, in key order.
Map.drop(%{a: 1, b: 2, c: 3}, 2) # => [3]fn drop_while(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- [V]The values after the leading ones for which pred holds.
Map.drop_while(%{a: 1, b: 2, c: 1}, \_ < 2) # => [2, 1]fn each(map :- Map[K, V], f :- fn(V, ?K) -> U)Calls f on every value (|v, k|: with the key) for its effect;
returns the last result.
Map.each(%{a: 1, b: 2}, |v, k| -> println(k, " = ", v))fn empty?(map :- Map[K, V]) :- BoolWhether the map has no entries.
Map.empty?(%{}) # => truefn entries(map :- Map[K, V]) :- [[K, V]]Returns the map entries as [[key, value], ...], ordered by sorted keys.
Example:
Map.entries(%{x: 10}) # => [x: 10]fn fetch(map :- Map[K, V], key) :- Result[V, String]Returns %Ok[value] for key, or %Err["..."] if the key is missing.
Example:
Map.fetch(%{a: 42}, :a) # => %Ok[42]fn filter(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- [V]The values for which pred holds, as an array. For a map use
Map.filter_entries.
Map.filter(%{a: 1, b: 2, c: 3}, \_ > 1) # => [2, 3]fn filter_entries(map :- Map[K, V], pred :- fn([K, V]) -> Bool)Returns a new map (with the same tag) containing only the entries for
which pred([key, value]) is truthy.
Example:
Map.filter_entries(%{a: 1, b: 2, c: 3}, |[_, v]| -> v > 1) # => %{ :b => 2, :c => 3 }fn find(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- Option[V]The first value (in key order) for which pred holds.
Map.find(%{a: 1, b: 5}, \_ > 4) # => %Some[5]fn find_map(map :- Map[K, V], f :- fn(V, ?K) -> Option[U]) :- Option[U]The first %Some[...] that f gives (f returns an Option).
Map.find_map(%{a: 1, b: 5}, |v, k| -> if v > 4 then %Some[k] else %None[]) # => %Some[:b]fn flat_map(map :- Map[K, V], f :- fn(V, ?K) -> [U]) :- [U]Maps every value to an array and joins them, one level.
Map.flat_map(%{a: 1, b: 2}, |v, k| -> [k, v]) # => [:a, 1, :b, 2]fn fold_left(map :- Map[K, V], acc :- A, f :- fn(A, V, ?K) -> A) :- AThe same as reduce, with the accumulator-first name.
Map.fold_left(%{a: "x", b: "y"}, "", |acc, v| -> acc <> v) # => "xy"fn from_entries(pairs) :- Result[Map[Any, Any], String]Builds a map from a list of [key, value] pairs.
Returns %Ok[map] or %Err["..."] for invalid input.
For keyword arrays like [a: 1, b: 2], use Map.from_keywords(...).
Example:
Map.from_entries([[:a, 1], [:b, 2]]) # => %Ok[%{ :a => 1, :b => 2 }]fn from_keywords(pairs) :- Result[Map[Any, Any], String]Builds a map from a keyword array like [a: 1, b: 2].
Returns %Ok[map] or %Err["..."] for invalid input.
Example:
Map.from_keywords([a: 1, b: 2]) # => %Ok[%{ :a => 1, :b => 2 }]fn get(map :- Map[K, V], key) :- Option[V]Returns %Some[value] for key, or %None[] if the key is missing.
Example:
Map.get(%{a: 42}, :a) # => %Some[42]
Map.get(%{a: 42}, :b) # => %None[]fn get_or(map :- Map[K, V], key, default :- D) :- V | DReturns the value for key, or default if the key is missing.
Example:
Map.get_or(%{a: 42}, :b, 99) # => 99fn has_key(map :- Map[K, V], key) :- BoolReturns true if key exists in the map (also key in map).
Example:
Map.has_key(%{a: 1}, :a) # => truefn keys(map :- Map[K, V]) :- [K]Returns the map keys as a list, sorted.
Example:
Map.keys(%{b: 2, a: 1}) # => [:a, :b]fn map(map :- Map[K, V], f :- fn(V, ?K) -> U) :- [U]Applies f to every value (|v, k|: with the key); the results
as an array. For a map with the same keys use Map.map_values.
Map.map(%{a: 1, b: 2}, |v, k| -> "$k=$v") # => [":a=1", ":b=2"]fn map_values(map :- Map[K, V], f :- fn(V) -> U)Applies f to each value and returns a new map with the same keys
(and tag).
Example:
Map.map_values(%{a: 1, b: 2}, |x| -> x * 10) # => %{ :a => 10, :b => 20 }fn member?(map :- Map[K, V], key) :- BoolWhether key is a KEY of the map (as key in map; the values are
not searched).
Map.member?(%{a: 1}, :a) # => true
Map.member?(%{a: 1}, 1) # => falsefn merge(a :- Map[K, V], b :- Map[K, W])Merges two maps, with entries from b overwriting entries from a.
If a is tagged, the tag is preserved.
Example:
Map.merge(%{a: 1, b: 2}, %{b: 99, c: 3}) # => %{ :a => 1, :b => 99, :c => 3 }fn merge_with(a :- Map[K, V], b :- Map[K, W], f :- fn(V, W) -> U)Merges two maps and resolves overlapping keys with f(left, right).
Example:
Map.merge_with(%{count: 1}, %{count: 2, size: 4}, |left, right| -> left + right) # => %{ :count => 3, :size => 4 }fn reduce(map :- Map[K, V], acc :- A, f :- fn(A, V, ?K) -> A) :- AFolds the values: f(acc, v) for every value, starting with acc
(|acc, v, k|: with the key).
Map.reduce(%{a: 1, b: 2}, 0, |acc, v| -> acc + v) # => 3fn reject(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- [V]The values for which pred does not hold, as an array.
Map.reject(%{a: 1, b: 2, c: 3}, \_ > 1) # => [1]fn select_keys(map :- Map[K, V], wanted_keys :- [K])Returns a fresh map containing only the entries whose keys appear in wanted_keys.
Missing keys are ignored.
Example:
Map.select_keys(%{name: "Ana", age: 42, city: "Berlin"}, [:name, :city]) # => %{ :city => "Berlin", :name => "Ana" }fn set(mut map :- Map[K, V], key, value)Mutates map in place by setting key to value and returns the mutated map.
Example:
my person = %{name: "Ana"}
Map.set(person, :age, 42)
person.age # => 42fn size(map :- Map[K, V]) :- IntReturns the number of entries in a map.
Example:
Map.size(%{a: 1, b: 2, c: 3}) # => 3fn take(map :- Map[K, V], n :- Int) :- [V]The first n values, in key order.
Map.take(%{a: 1, b: 2, c: 3}, 2) # => [1, 2]fn take_while(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- [V]The leading values (in key order) for which pred holds.
Map.take_while(%{a: 1, b: 2, c: 1}, \_ < 2) # => [1]fn to_array(map :- Map[K, V]) :- [V]The values as an array, in key order (the same as Map.values).
Map.to_array(%{b: 2, a: 1}) # => [1, 2]fn to_keywords(map :- Map[K, V]) :- [[K, V]]Converts a map to a keyword-array-style list of [key, value] entries.
Example:
Map.to_keywords(%{a: 1, b: 2}) # => [a: 1, b: 2]fn update(map :- Map[K, V], key, f)Returns a fresh map with the value at key updated by f.
Missing values are passed to f as undef.
Example:
my updated = Map.update(%{age: 41}, :age, |age| -> age + 1)
updated.age # => 42fn update_in(map :- Map[Any, Any], path :- [Any], f)Returns a fresh map with the nested value at path updated by f.
Missing intermediate maps are created automatically, and missing leaf
values are passed to f as undef.
Example:
my updated = Map.update_in(%{user: %{age: 41}}, [:user, :age], |age| -> age + 1)
updated.user.age # => 42fn values(map :- Map[K, V]) :- [V]Returns the map values as a list, ordered by sorted keys.
Example:
Map.values(%{b: 2, a: 1}) # => [1, 2]fn zip(map :- Map[K, V], other :- Seq[B]) :- [[V, B]]Pairs the values (in key order) with the elements of another sequence, up to the shorter one.
Map.zip(%{a: 1, b: 2}, ["x", "y"]) # => [[1, "x"], [2, "y"]]fn zip_with(map :- Map[K, V], other :- Seq[B], f :- fn(V, B) -> C) :- [C]Combines the values with the elements of another sequence, up to the shorter one.
Map.zip_with(%{a: 1, b: 2}, [10, 20], |v, x| -> v + x) # => [11, 22]