1# maps - operations on maps and objects.2#3# Reading a missing key gives null, which is indistinguishable from a null4# stored on purpose: Has answers that question, Get gives a default.56cmp = import("cmp")78# Has reports whether m holds the key k.9Has = fn(m, k) {10 ks = keys(m)11 for i = 0; i < len(ks); ++i {12 if cmp.Equal(ks[i], k) {13 return true14 }15 }16 return false17}1819# Get returns m[k], or def if the key is absent.20Get = fn(m, k, def) {21 if Has(m, k) {22 return m[k]23 }24 return def25}2627# Keys returns the keys of m. Works on objects too, where they are the names28# of the fields.29Keys = fn(m) { keys(m) }3031# Values returns the values of m, in the same order as Keys.32Values = fn(m) {33 ks = keys(m)34 out = []35 for i = 0; i < len(ks); ++i {36 out = append(out, m[ks[i]])37 }38 return out39}4041# Len returns the number of entries.42Len = fn(m) { len(keys(m)) }4344# Each calls f(key, value) for every entry.45Each = fn(m, f) {46 ks = keys(m)47 for i = 0; i < len(ks); ++i {48 f(ks[i], m[ks[i]])49 }50}5152# Merge returns a new map with the entries of a and b, those of b winning.53Merge = fn(a, b) {54 out = {}55 Each(a, fn(k, v) { out[k] = v })56 Each(b, fn(k, v) { out[k] = v })57 return out58}5960# Equal reports whether two maps hold the same entries.61Equal = fn(a, b) { cmp.Equal(a, b) }