Maps
String-keyed hash maps with `{ }` literals and bracket access.
Maps are string-keyed hash tables. Create them with { "key": value, ... }: keys in literals must be double-quoted strings; values can be any Rain value.
Read and write with map["key"]. Use any string expression as the key, e.g. freq[word] inside a loop. A missing key returns nil instead of raising an error.
Empty maps are written {}. You can build them at runtime with var m = {}; or start from a literal and add keys with m["key"] = value.
Maps nest cleanly: values can be other maps, arrays, or any Rain value. Use bracket access to drill in: outer["inner"]["leaf"].
Call built-in map methods with map->method(): same -> syntax as arrays. Use ->keys(), ->values(), ->has(key), ->delete(key), and ->len() to inspect and mutate maps without writing your own loops.
Iterate a map with **for (key, value von map)**: two names separated by a comma before von. Each pass binds one entry's key and value. An empty map simply skips the loop body.
Literal & access
Create a map with quoted keys, read values with `["key"]`, and add or overwrite entries.
var config = {
"host": "localhost",
"port": 5432,
"debug": true,
"name": "raindb"
};
print config["host"];
print config["port"];
print config["debug"];
config["port"] = 3306;
print config["port"];
config["newfield"] = "added";
print config["newfield"];
print config["missing"];localhost 5432 true 3306 added nil
Dynamic keys
Use any string expression as a key: handy for counting or grouping in a loop.
var freq = {};
var words = #["apple", "banana", "apple", "cherry", "banana", "apple"];
for (w von words) {
if (freq[w] == nil) {
freq[w] = 1;
} else {
freq[w] = freq[w] + 1;
}
}
print freq["apple"];
print freq["banana"];
print freq["cherry"];3 2 1
Iterate with for-von
Loop every key/value pair with `for (key, value von map)`. Order follows hash buckets, not source order.
var scores = {"Alice": 95, "Bob": 87, "Carol": 92};
for (name, score von scores) {
print "#{name} scored #{score}";
}Carol scored 92 Bob scored 87 Alice scored 95
Empty map
An empty `{}` is valid. A `von` loop over it simply skips the body.
var empty = {};
for (k, v von empty) {
print "never runs";
}
print "done";done
Nested maps and nested von
Maps can hold other maps. Use nested `for (k, v von …)` loops to walk each level.
var nested = {
"a": {"x": 1, "y": 2},
"b": {"p": 9}
};
for (outerKey, inner von nested) {
print "outer=#{outerKey}";
for (innerKey, val von inner) {
print " #{innerKey}=#{val}";
}
}outer=a y=2 x=1 outer=b p=9
Nested maps and arrays
Combine maps and arrays, e.g. a list of user records, each with its own fields.
var db = {
"users": #[
{"id": 1, "name": "Alice", "scores": #[90, 85, 92]},
{"id": 2, "name": "Bob", "scores": #[78, 88, 95]}
]
};
for (user von db["users"]) {
var scores = user["scores"];
var total = scores#[0] + scores#[1] + scores#[2];
var avg = total / 3;
print "#{user["name"]}: avg=#{avg}";
}Alice: avg=89 Bob: avg=87
Building a map in a function
Start with `{}` and fill keys in a loop: useful when keys come from parallel arrays.
fun mapFromArrays(keys, vals) {
var result = {};
var i = 0;
while (i < keys->len()) {
result[keys#[i]] = vals#[i];
i = i + 1;
}
return result;
}
var mapped = mapFromArrays(#["a", "b", "c"], #[1, 2, 3]);
print mapped["a"];
print mapped["b"];
print mapped["c"];1 2 3
Map methods
Use `->` to call built-in helpers: list keys/values, test membership, remove entries, and read the entry count.
var m = {"a": 1, "b": 2, "c": 3};
print m->len();
print m->has("a");
print m->has("z");
m->delete("c");
print m->len();
print m->keys();
print m->values();3 true false 2 #["a", "b"] #[1, 2]
has() in a frequency counter
Prefer `->has(key)` over `map[key] == nil` when you only need to know if a key exists.
var freq = {};
var words = #["apple", "banana", "apple", "cherry"];
for (w von words) {
if (freq->has(w)) {
freq[w] = freq[w] + 1;
} else {
freq[w] = 1;
}
}
print freq->len();
print freq->has("apple");
print freq["apple"];3 true 2
Map methods
Call built-in methods with `->`. `keys()` and `values()` return new arrays; order follows the map's hash buckets (same as `for (k, v von map)`).
| Symbol | Description | Example |
|---|---|---|
->len() | Entry count | var m = {"a": 1, "b": 2};
print m->len(); |
->keys() | All keys as an array | var m = {"x": 1, "y": 2};
print m->keys(); |
->values() | All values as an array | var m = {"x": 1, "y": 2};
print m->values(); |
->has(key) | Whether key exists (string) | var m = {"a": 1};
print m->has("a");
print m->has("z"); |
->delete(key) | Remove key; returns nil | var m = {"a": 1, "b": 2};
m->delete("a");
print m->len(); |