Maps
Look up values by key.
On this page
Map[T] stores values by String key. HashMap[K, V] does the same for other key types.
Create and update a map#
Valk
fn main() {
let stock = Map[int]{ "notebook" => 12, "pencil" => 30 }
stock.set("eraser", 8)
stock["ruler"] = 3
stock.remove("pencil")
println(stock.length) // 3
println(stock.has("pencil")) // false
let empty = Map[String]{}
let typed: Map[bool] = .{ "debug" => true }
println("%{empty.length} %{typed.length}") // 0 1
}
Look up a value#
Valk
fn main() {
let stock = Map[int]{ "notebook" => 12 }
println(stock.get("notebook") !? 0) // 12
println(stock.get("stapler") !? -1) // -1: get throws for a missing key
println(stock["stapler"]) // 0: [] gives the zero value
let labels = Map[String]{ "a" => "Apple" }
println(labels["b"] ?? "none") // none: null for a missing object
}
get(key)throwsLookupError.missingwhen the key is absent.map[key]gives0,falseornullfor a missing key. For a class orStringvalue its type is nullable, so use??.
Loop over a map#
Valk
fn main() {
let stock = Map[int]{ "pen" => 3, "cup" => 0, "box" => 5 }
each stock as count, item {
if count == 0 : stock.remove(item) // removing while looping is safe
}
each stock as count, item, index : println("%index %item: %count")
let keys = stock.keys()
keys.sort()
println(keys.join(", ")) // box, pen
}
Entries are visited in insertion order; removing one can change that order. Call sort_keys() to order a Map by key.
Count and update in place#
Valk
fn main() {
let counts = Map[uint]{}
each "the cat and the hat".words() as word {
counts.add(word, 1)
}
println(counts["the"]) // 2
let scores = Map[int]{}
scores["ada"] += 5 !? 0 // a missing key starts at 0
scores.update("sam", fn(old) { return (old ?? 0) + 10 })
println("%{scores["ada"]} %{scores["sam"]}") // 5 10
}
add works on maps of uint. update gets the old value, or null, and stores what the function returns.
Other key types#
Valk
struct Point {
x: int
y: int
}
fn main() {
let names = HashMap[uint, String]{ 5 => "five", 10 => "ten" }
println(names[5] ?? "") // five
let grid = HashMap[Point, String]{}
grid.set(Point { x: 1, y: 2 }, "tree")
println(grid.get(Point { x: 1, y: 2 }) !? "") // tree
let pairs = HashMap[(int, int), bool]{ (0, 1) => true }
println(pairs.has((0, 1))) // true
}
Keys can be integers, strings, structs, tuples, fixed arrays of those, or any type with a hash method. A struct with a float or with its own == needs its own hash.
Map[T] is a HashMap[String, T], and the two convert to each other freely.
Methods#
| Method | Effect |
|---|---|
set(key, value), map[key] = value |
Add or replace |
set_unique(key, value) |
Add; throws exists when the key is there |
get(key) |
Value; throws when missing |
has(key), has_value(value) |
bool |
remove(key) |
Remove one entry |
remove_where(fn), retain(fn) |
Remove or keep entries the function accepts |
keys(), values() |
Array of keys or values |
length, is_empty(), clear() |
Size and reset |
merge(other), merge_in_place(other) |
Combine maps; other wins on equal keys |
copy(), clone() |
Shallow or deep copy |
sort_keys() |
Order entries by key |
For a small map that keeps insertion order also after removals, use FlatMap. To share a map between threads, see Sharing data between threads.
