Maps
A Map(K, V) is an insertion-ordered dictionary. K is Int or String. Lookup, insertion and update are O(1): the entries stay a dense array in arrival order, with a hash index over it.
func main():
var ages = new Map(String, Int)
ages["ada"] = 36
ages["grace"] = 45
ages["alan"] = 41
ages["ada"] += 1 # the key is evaluated once
for name, age in ages:
print(f"{name} is {age}")
print(f"{len(ages)} people")
print(f"has grace: {ages.has("grace")}")
print(f"get nobody: {ages.get("nobody", -1)}")
ages.remove("alan")
ages.remove("nobody") # absent: a no-op, not an error
print(f"{len(ages)} left")ada is 37 grace is 45 alan is 41 3 people has grace: true get nobody: -1 2 left
Indexing a key that is not there is a trap, on purpose. Asking a map for something you did not put in it is a bug in the program, not news from the world — so guard with has, or use get(key, default), which cannot trap.
func main():
var ages = new Map(String, Int)
ages["ada"] = 36
print(str(ages["nobody"]))loom: trap: key not found in map [key_missing]
at main (main.luc:4:5)Counting#
The Map counting idiom, which is what most real uses are:
import std.strings
func main():
let text = "the cat sat on the mat the end"
var counts = new Map(String, Int)
for word in text.split(" "):
counts[word] = counts.get(word, 0) + 1
for word, seen in counts:
if seen > 1:
print(f"{word}: {seen}")the: 3
keys() and values() hand back fresh lists the receiver owns.
func main():
var stock = new Map(Int, String)
stock[3] = "fig"
stock[1] = "pear"
let ids = stock.keys()
let names = stock.values()
print(f"{len(ids)} keys, first {ids[0]}")
print(f"{len(names)} values, first {names[0]}")2 keys, first 3 2 values, first fig