Standard Library
class Map<K, V>
An associative collection from keys of type K to values of type V, with value semantics.
since 0.1.0-alpha.1linuxwindowswasm
- bases
IIterable<Pair<K, V>>
Overview
Like Array, a map is never changed in place: with and without return a new map, and the
index assignment m[k] = v rebinds the variable to an updated copy. Entries keep the order in
which their keys were first added, and keys, values, entries and for loops all follow
that order. Updating the value of an existing key does not move it.
Keys are compared by value for numbers, strings and bool, field by field for structs, and by
identity for class instances. Read a value with m[k] or at, which throw when the key is
missing; use has, atOrNone or atOr when it might be. for (Pair<K, V> e in m) visits
the entries as pairs with first (the key) and second (the value). Printing a map with
console.writeln shows it as {key: value, ...}.
Description
Map<K, V> associates keys with values. Like Array, it is a pure value: no method changes the
map it is called on. The changing operations return a new map, and the idiom is to rebind the
variable. Because get and set are keywords, the vocabulary is at to read, with(key, value)
to add or replace, and without(key) to remove. The bracket form m[k] = v is shorthand for
m = m.with(k, v), and m[k] reads like m.at(k).
Create an empty map with Map(), or with a declaration that has no initializer,
Map<string, int> m;. A map prints as {a: 1, b: 2}.
Order. A map remembers insertion order. keys(), values(), entries(), a for loop and
printing all follow it. Replacing the value of a key that is already present keeps the key where it
was. Removing a key and adding it again moves it to the end.
Key equality. Primitive keys (int, string, bool, ...) compare by value. A struct key
compares field by field, so two separately built Pt(1, 2) values are the same key. A class key
compares by identity: two distinct objects are different keys even when their fields match.
Missing keys. at(k) and m[k] throw RuntimeException (with the message key not found: ...)
when the key is absent. Use has(k) to test, atOrNone(k) to get a V?, or atOr(k, fallback) to get a default.
Iteration. for (Pair e in m) visits each entry as a Pair, with the key in e.first and the
value in e.second, in insertion order. entries() returns the same pairs as an Array.
Building, reading and iterating a map
Map<string, int> m = Map();
m = m.with("b", 2).with("a", 1).with("c", 3);
console.writeln(m);
m = m.with("b", 20);
console.writeln(m);
m = m.without("a");
console.writeln(m);
console.writeln(m.keys());
console.writeln(m.values());
console.writeln(m.has("c"));
console.writeln(m.length());
console.writeln(m.atOr("zz", -1));
console.writeln(m.atOrNone("zz") == None);
console.writeln(m.atOrNone("c"));
m["d"] = 4;
for (Pair e in m) { console.writeln("${e.first}=${e.second}"); }
console.writeln(m);
{b: 2, a: 1, c: 3}
{b: 20, a: 1, c: 3}
{b: 20, c: 3}
[b, c]
[20, 3]
true
2
-1
true
3
b=20
c=3
d=4
{b: 20, c: 3, d: 4}
Rules
- No method mutates the receiver;
withandwithoutreturn a new map. Seelang.collection-value-semantics. m[k] = vis a rebind of the variablem.- Iteration,
keys,valuesandentriesfollow insertion order. Replacing a value keeps its key's position; a removed and re-added key goes to the end. - Struct keys are equal field by field; class keys are equal only when they are the same object.
atandm[k]throw on a missing key;atOrNoneandatOrdo not.withAll(other)adds every entry ofother,mapValues(f)transforms the values and keeps the keys, andwhereEntries(pred)keeps the entries for whichpred(key, value)is true. Each returns a new map.
Examples
Struct keys, class keys and bulk operations
struct Pt { int x; int y; }
class Tag { string n; }
Map<Pt, string> byPoint = Map();
byPoint = byPoint.with(Pt(1, 2), "a").with(Pt(1, 2), "b").with(Pt(3, 4), "c");
console.writeln(byPoint.length());
console.writeln(byPoint.at(Pt(1, 2)));
Tag t1 = Tag("k");
Tag t2 = Tag("k");
Map<Tag, int> byTag = Map();
byTag = byTag.with(t1, 1).with(t2, 2).with(t1, 3);
console.writeln(byTag.length());
console.writeln(byTag.at(t1));
Map<string, int> a = Map();
a = a.with("x", 1).with("y", 2).with("z", 3);
console.writeln(a.mapValues((v) => v * 10));
console.writeln(a.whereEntries((k, v) => v > 1));
Map<string, int> extra = Map();
extra = extra.with("z", 0).with("w", 9);
console.writeln(a.withAll(extra));
console.writeln(a.entries().length());
Map<int, string> im = Map();
im = im.with(5, "five").with(1, "one").without(5).with(5, "again");
console.writeln(im);
2
b
2
3
{x: 10, y: 20, z: 30}
{y: 2, z: 3}
{x: 1, y: 2, z: 0, w: 9}
3
{1: one, 5: again}
Map<string, int> ages = Map();
ages = ages.with("ann", 30);
try {
console.writeln(ages.at("bob"));
} catch (RuntimeException e) {
console.writeln(e.message);
}
The catch block prints key not found: bob.
Notes
A map stored in a class field is rebound like any other variable: index = index.with(k, v);.
An Array.groupBy call returns a Map from each key to the array of elements that produced it.
Examples
Counting words
Map<string, int> counts = Map();
for (string w in ["a", "b", "a", "c", "a"]) {
counts[w] = counts.atOr(w, 0) + 1;
}
console.writeln(counts);
console.writeln(counts.length());
for (Pair<string, int> e in counts) {
console.writeln("${e.first} -> ${e.second}");
}
{a: 3, b: 1, c: 1}
3
a -> 3
b -> 1
c -> 1
Constructors
new
new()Create an empty map.
Map<string, int> m; with no initializer is the same empty map.
Examples
An empty map
Map<string, int> m = Map();
console.writeln(m.length());
m["x"] = 1;
console.writeln(m);
0
{x: 1}
Accessors
[]
get [](K key)The value stored under key, written m[key].
Assigning to a key, m[key] = val, rebinds the variable to an updated copy of the map (the same
result as with); other variables that held the old map still see the old value.
Parameters
- key
- The key to look up.
Throws
RuntimeException- when the map has no entry for
key.
Examples
Indexing and index assignment
Map<string, int> a = Map();
a["x"] = 1;
Map<string, int> b = a;
b["x"] = 2;
console.writeln(a["x"]);
console.writeln(b["x"]);
1
2
Methods
at
at(K key) -> VThe value stored under key.
m.at(k) and m[k] are the same operation.
Parameters
- key
- The key to look up.
Returns
The value for key.
Throws
RuntimeException- when the map has no entry for
key.
Examples
Reading a value
Map<string, int> m = Map();
m["a"] = 1;
console.writeln(m.at("a"));
console.writeln(m.has("zz") ? m.at("zz") : -1);
1
-1
A missing key throws
Map<string, int> m = Map();
m["a"] = 1;
try {
console.writeln(m.at("zz"));
} catch (RuntimeException e) {
console.writeln("caught: ${e.message}");
}
atOr
atOr(K key, V dflt) -> VThe value stored under key, or dflt when the key is missing.
The map itself is not changed; the default is not stored.
Parameters
- key
- The key to look up.
- dflt
- The value to return when
keyis not present.
Returns
The stored value, or dflt.
Examples
Counting with a default
Map<string, int> m = Map();
m["a"] = 5;
console.writeln(m.atOr("a", 0));
console.writeln(m.atOr("b", 0));
console.writeln(m.has("b"));
5
0
false
See also: atOrNone
atOrNone
atOrNone(K key) -> V | NoneThe value stored under key, or None when the key is missing.
Parameters
- key
- The key to look up.
Returns
The value, or None if there is no entry for key.
Examples
A missing key gives None
Map<string, int> m = Map();
m["a"] = 1;
console.writeln(m.atOrNone("a"));
console.writeln(m.atOrNone("b"));
1
None
entries
The entries as an array of Pair<K, V>, in insertion order.
Each pair has the key as first and the value as second.
Returns
A new array with one pair per entry.
Examples
Entries as pairs
Map<string, int> m = Map();
m["a"] = 1;
m["b"] = 2;
for (Pair<string, int> e in m.entries()) {
console.writeln("${e.first}: ${e.second}");
}
a: 1
b: 2
has
has(K key) -> boolWhether the map has an entry for key.
Parameters
- key
- The key to test.
Returns
true if key is present.
Examples
Testing for a key
Map<string, int> m = Map();
m["a"] = 0;
console.writeln(m.has("a"));
console.writeln(m.has("b"));
true
false
isEmpty
isEmpty() -> boolWhether the map has no entries.
Returns
true when length() is 0.
Examples
Emptiness
Map<string, int> m = Map();
console.writeln(m.isEmpty());
m["a"] = 1;
console.writeln(m.isEmpty());
true
false
iterator
Return an iterator over the entries as Pair<K, V>, in insertion order.
This is what lets a map be passed where an IIterable<Pair<K, V>> is expected. A for loop
over a map does not need it. The iterator walks a snapshot of the map as it was when the
iterator was created.
Returns
An iterator positioned before the first entry.
Examples
Walking a map by hand
Map<string, int> m = Map();
m["a"] = 1;
m["b"] = 2;
IIterator<Pair<string, int>> it = m.iterator();
while (it.hasNext()) {
Pair<string, int> e = it.next();
console.writeln("${e.first}=${e.second}");
}
a=1
b=2
keys
keys() -> Array<K>The keys, in the order they were first added.
Returns
A new array of the keys.
Examples
Listing keys
Map<string, int> m = Map();
m["b"] = 2;
m["a"] = 1;
console.writeln(m.keys());
[b, a]
See also: values
length
length() -> intThe number of entries.
Returns
How many keys the map holds.
Examples
Counting entries
Map<string, int> m = Map();
m["a"] = 1;
m["b"] = 2;
m["a"] = 3;
console.writeln(m.length());
2
mapValues
mapValues<U>((V) => U fn) -> Map<K, U>Return a new map with the same keys whose values are fn applied to the old values.
The keys keep their order. The value type of the result may differ from V. The receiver is not
changed.
Parameters
- fn
- The transformation applied to each value.
Returns
A new map with transformed values.
Examples
Doubling values
Map<string, int> m = Map();
m["a"] = 1;
m["b"] = 2;
console.writeln(m.mapValues((v) => v * 2));
console.writeln(m.mapValues((v) => "n" + v.toString()));
{a: 2, b: 4}
{a: n1, b: n2}
values
values() -> Array<V>The values, in the same order as keys.
Returns
A new array of the values; element i belongs to key i of keys().
Examples
Listing values
Map<string, int> m = Map();
m["b"] = 2;
m["a"] = 1;
console.writeln(m.values());
[2, 1]
See also: keys
whereEntries
whereEntries((K, V) => bool pred) -> Map<K, V>Return a new map with only the entries for which pred is true.
The kept entries keep their order. The receiver is not changed.
Parameters
- pred
- Called with each key and value; the entry is kept when it returns
true.
Returns
A new map holding the matching entries.
Examples
Keeping large values
Map<string, int> m = Map();
m["a"] = 1;
m["b"] = 20;
m["c"] = 30;
console.writeln(m.whereEntries((k, v) => v > 10));
console.writeln(m.whereEntries((k, v) => k == "a"));
{b: 20, c: 30}
{a: 1}
with
with(K key, V val) -> Map<K, V>Return a new map in which key maps to val.
If key is already present its value is replaced and it keeps its position; otherwise the entry
is added at the end. The receiver is not changed. The index assignment m[key] = val does the
same and rebinds the variable.
Parameters
- key
- The key to add or update.
- val
- The value to store.
Returns
A new map with the change applied.
Examples
Adding and replacing
Map<string, int> a = Map();
Map<string, int> b = a.with("x", 1).with("y", 2);
Map<string, int> c = b.with("x", 9);
console.writeln(a);
console.writeln(b);
console.writeln(c);
{}
{x: 1, y: 2}
{x: 9, y: 2}
See also: without
withAll
Return a new map holding the entries of this map overlaid with the entries of o.
Where both maps have a key, the value from o wins and the key keeps its position from this
map. Keys only in o are added after the existing ones. Neither input is changed.
Parameters
- o
- The map whose entries are added or take precedence.
Returns
The merged map.
Examples
Merging with overrides
Map<string, int> a = Map();
a["x"] = 1;
a["y"] = 2;
Map<string, int> b = Map();
b["y"] = 20;
b["z"] = 30;
console.writeln(a.withAll(b));
console.writeln(a);
{x: 1, y: 20, z: 30}
{x: 1, y: 2}
without
without(K key) -> Map<K, V>Return a new map without key.
If key is not present the result is equal to the receiver. The receiver is not changed.
Parameters
- key
- The key to remove.
Returns
A new map with the entry removed.
Examples
Removing an entry
Map<string, int> m = Map();
m["a"] = 1;
m["b"] = 2;
console.writeln(m.without("a"));
console.writeln(m.without("zz"));
console.writeln(m);
{b: 2}
{a: 1, b: 2}
{a: 1, b: 2}
See also: with
See also
- Set — A collection of distinct values of type
T, with value semantics. - Collections are values — Array, Map and Set never change in place; every changing method returns a new collection, and the idiom for change is to rebind.
- Pair — A pair of two values, possibly of different types.
- Array — An ordered sequence of values of one type,
Array<T>, with value semantics.