Dictionary

A Dictionary is an ordered collection of key-value pairs. Keys are always strings. Values can be any type, including other dictionaries and lists.

Literal syntax

Dictionaries are written with curly braces. Keys can be bare identifiers or quoted strings.

{}
{ name: "Widget", price: 42 }
{ "Content-Type": "text/html" }

Use quoted keys when a key contains hyphens, spaces, or other characters that are not valid in a bare identifier.

Trailing commas are allowed:

{
  name: "Widget",
  price: 42,
}

Dictionaries can be nested:

{
  product: { name: "Widget", price: 42 },
  meta: { tags: ["sale", "new"] }
}

Access

Dot access

Use dot notation to read a value by a known key:

product.name
product.price

Subscript access

Use square brackets to read a value by a string expression or a dynamic key:

product["name"]
product[dynamicKey]

Dot access and subscript access return null when the key does not exist.

Property assignment

Dictionaries bound to a let variable support property assignment for building up data structures.

Dot assignment

let product = {};
product.name = "Widget";
product.price = 9.99;
product

Subscript assignment

let product = {};
let key = "name";
product[key] = "Widget";
product

Both forms add the key if it is absent or replace its value if it already exists.

For more detail on let bindings, see Variables and Composition.

Methods

.keys()

Returns a list of all keys in insertion order.

{ name: "Widget", price: 42 }.keys()
// ["name", "price"]

Returns: list

.values()

Returns a list of all values in insertion order.

{ name: "Widget", price: 42 }.values()
// ["Widget", 42]

Returns: list

.entries()

Returns a list of { key, value } dictionaries, one per entry, in insertion order.

{ name: "Widget", price: 42 }.entries()
// [{ key: "name", value: "Widget" }, { key: "price", value: 42 }]

Returns: list

.contains(key)

Returns true if the dictionary has an entry for key, false otherwise.

{ name: "Widget" }.contains("name")   // true
{ name: "Widget" }.contains("price")  // false

Returns: boolean

.count()

Returns the number of entries in the dictionary.

{ name: "Widget", price: 42 }.count()
// 2

Returns: number

.isEmpty()

Returns true if the dictionary has no entries.

{}.isEmpty()
// true
{ name: "Widget" }.isEmpty()
// false

Returns: boolean

.get(key, default)

Returns the value for key if it exists, otherwise evaluates and returns default. Unlike dot or subscript access (which return null for missing keys), .get() lets you provide a fallback inline.

{ name: "Widget" }.get("name", "Unknown")    // "Widget"
{ name: "Widget" }.get("price", 0)           // 0

Both arguments are required.

Returns: any

.delete(key)

Returns a new dictionary with the entry for key removed. The original dictionary is unchanged. If the key does not exist, the returned dictionary is identical to the original.

{ name: "Widget", price: 42 }.delete("price")
// { name: "Widget" }

{ name: "Widget" }.delete("missing")
// { name: "Widget" }

Returns: dictionary

.merge(other)

Returns a new dictionary combining entries from both dictionaries. If a key exists in both, the value from other wins.

{ name: "Widget", price: 42 }.merge({ price: 50, stock: 10 })
// { name: "Widget", price: 50, stock: 10 }

Returns: dictionary

See also