Objects and maps
Group named values into objects, look things up by key with typed maps, and loop over both.
An object groups values under names, called keys. Write it in curly braces:
object book = {
title: "Dune",
author: "Frank Herbert",
year: 1965
}
log book.title
log book["year"]
log bookRead a value with a dot, or with the key in square brackets when the key is in a variable or isn't a plain name. Objects print as JSON, with their keys in alphabetical order.
Changing objects#
Assign to a key to change it, or to add it if it isn't there yet. delete removes keys:
object user = {name: "Ada"}
user.age = 36
user["role"] = "admin"
log user
user.delete("role")
log userMissing keys#
Reading a key that isn't there gives null, so pair it with ?? for a default:
object settings = {theme: "dark"}
log settings.language
log settings.language ?? "en"
log settings.contains("theme")Nesting#
Values can be arrays or other objects, as deep as you like. This is the same shape as JSON, which is why objects are what you get when you parse JSON:
object order = {
id: 1042,
customer: {name: "Grace", city: "Arlington"},
items: ["keyboard", "mouse"]
}
log order.customer.name
log order.items[2]
order.items.append("cable")
log order.items.lenLooping over objects#
for key, value in walks every entry. getKeys and getValues give you the keys or values as arrays. An object doesn't keep its keys in any particular order, so sort the keys when the order matters:
object stock = {apples: 12, pears: 0, plums: 7}
for name in stock.getKeys().sort() (
log name ++ ": " ++ stock[name]
)
log stock.getValues().sum()
int total = 0
for _, count in stock (
total += count
)
log totalTyped maps#
object holds values of any type, which is flexible but means the compiler can't check much. When every value has the same type, use a typed map. string[int] reads as "keys are strings, values are ints":
string[int] wordCounts = {}
for word in "the cat and the hat".split(" ") (
wordCounts[word] = (wordCounts[word] ?? 0) + 1
)
log wordCounts
log wordCounts["the"]The compiler now knows every value is an int, so wordCounts["the"] + 1 is checked and fast, and putting a string in by mistake is a compile error:
string[int] ages = {}
ages["ada"] = "thirty-six"Building objects from variables#
When a key and a variable share a name, write it once. ... spreads one object into another, and later keys win:
string name = "Ada"
int level = 3
object player = {name, level}
log player
object defaults = {sound: true, speed: 1}
object chosen = {...defaults, speed: 2}
log chosen++ merges two objects the same way: defaults ++ {speed: 2}.
Taking objects apart#
Destructuring pulls named keys into variables:
object point = {x: 3, y: 4, label: "P"}
{x, y} = point
log x ySharing and copying#
Like arrays, objects are shared when you assign them. .clone() makes an independent copy:
object first = {count: 0}
object second = first
second.count = 1
log first.count
object third = first.clone()
third.count = 99
log first.countobject o = {a: 1}. What does log o.b print?
Total stock
Print the total number of items in stock, and then the names of the items that have run out, in alphabetical order.
42 ["bread","milk"]