Map Methods

Maps in Risor have built-in methods for iterating, accessing, and modifying key-value pairs. Some methods mutate the map in place while others return new values.

Method Reference

MethodMutatesDescription
keys()NoIterator over the map's keys
values()NoIterator over the map's values
entries()NoIterator over [key, value] pairs
each(fn)NoIterate over key-value pairs
get(key, default?)NoGet a value with an optional default
copy()NoShallow copy of the map
pop(key)YesRemove and return a value by key
setdefault(key, value)YesSet a key if missing, return the value
update(map)YesMerge another map into this one
clear()YesRemove all entries

Iteration

keys

Return an iterator over the map's keys. Use list() to materialize the iterator into a list.

let config = {host: "localhost", port: 8080}
config.keys()         // iter("host", "port")
list(config.keys())   // ["host", "port"]

values

Return an iterator over the map's values.

let config = {host: "localhost", port: 8080}
config.values()         // iter("localhost", 8080)
list(config.values())   // ["localhost", 8080]

entries

Return an iterator over [key, value] pairs.

let config = {host: "localhost", port: 8080}
list(config.entries())  // [["host", "localhost"], ["port", 8080]]

each

Iterate over key-value pairs, calling the given function for each one. Returns nil. The callback receives the key as the first argument and the value as the second.

let config = {host: "localhost", port: 8080}
config.each((k, v) => sprintf("%s=%v", k, v))
// prints: host localhost
// prints: port 8080

Access

get

Get a value by key. If the key does not exist, return the optional default value. Without a default, returns nil.

let config = {host: "localhost", port: 8080}
config.get("host")           // "localhost"
config.get("timeout")        // nil
config.get("timeout", 30)    // 30

Mutation

pop

Remove a key from the map and return its value.

let config = {host: "localhost", port: 8080}
config.pop("host")   // "localhost"
// config == {port: 8080}

setdefault

Set a key to the given value only if the key does not already exist. Returns the value associated with the key (either the existing value or the newly set one).

let config = {host: "localhost"}
config.setdefault("host", "0.0.0.0")    // "localhost" (already set)
config.setdefault("debug", false)        // false (newly set)
// config == {host: "localhost", debug: false}

update

Merge another map into this one. Existing keys are overwritten by the values from the argument map.

let config = {host: "localhost", port: 8080}
config.update({port: 9090, debug: true})
// config == {host: "localhost", port: 9090, debug: true}

clear

Remove all entries from the map.

let config = {host: "localhost", port: 8080}
config.clear()
// config == {}

copy

Return a shallow copy of the map.

let original = {a: 1, b: 2}
let cloned = original.copy()
cloned.update({c: 3})
// original == {a: 1, b: 2}
// cloned == {a: 1, b: 2, c: 3}

Method Shadowing

Map methods shadow keys with the same name. If a map has a key that matches a method name (e.g. keys, get, values), the method takes priority when using dot notation. Use bracket notation to access the key instead.

let data = {keys: [1, 2, 3], values: "hello"}
 
data.keys         // the keys() method, not the list [1, 2, 3]
data["keys"]      // [1, 2, 3]
data["values"]    // "hello"

As a general rule, avoid using method names as map keys. If you must, always access those keys with bracket notation.


Risor © 2026 Deep Noodle