Antra

Standardbibliothek

Antra::Map

import Antra::Map

Functional 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#

fn all(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- Bool

Whether pred holds for every value; true for an empty map.

Map.all(%{a: 2, b: 4}, \_ % 2 == 0)   # => true
fn any(map :- Map[K, V], pred :- fn(V, ?K) -> Bool) :- Bool

Whether pred holds for some value.

Map.any(%{a: 1, b: 5}, \_ > 4)   # => true
fn 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            # => 42
fn 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   # => 42
fn 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) :- Int

The 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)      # => 1
fn 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)   # => false
fn 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)   # => false
fn 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)   # => false
fn 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]) :- Bool

Whether the map has no entries.

Map.empty?(%{})   # => true
fn 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) :- A

The 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 | D

Returns the value for key, or default if the key is missing.

Example:

Map.get_or(%{a: 42}, :b, 99)   # => 99
fn has_key(map :- Map[K, V], key) :- Bool

Returns true if key exists in the map (also key in map).

Example:

Map.has_key(%{a: 1}, :a)   # => true
fn 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) :- Bool

Whether 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)    # => false
fn 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) :- A

Folds 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)   # => 3
fn 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   # => 42
fn size(map :- Map[K, V]) :- Int

Returns the number of entries in a map.

Example:

Map.size(%{a: 1, b: 2, c: 3})   # => 3
fn 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   # => 42
fn 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   # => 42
fn 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]

Quelle dieser Seite