Collections
API summary (generated from the Beans source by npm run coverage): 3 types · 44 instance methods.
Beans has three builtin collection types: List for an ordered sequence, and
Map and OrderedMap for key-value lookups. All three are generic, so you name
the element or key/value types. They are native builtins with no .b source, so
their method signatures are positional: the type in each slot is fixed, the names
are not.
List, Map, and OrderedMap are move-only outer handles. When you bind,
assign, or return one, use move; function parameters borrow by default. Calling a
method that changes the collection needs a var binding. See
the memory model for what that means.
List<T>
Section titled “List<T>”List<T> holds items of type T in order. Write a list literal with square
brackets:
let nums: List<int> = [1, 2, 3]List<T>.len() -> intList<T>.is_empty() -> boolList<T>.first() -> Option<T>List<T>.last() -> Option<T>List<T>.get(int) -> Option<T>List<T>.contains(T) -> boolList<T>.index_of(T) -> Option<int>List<T>.max() -> Option<T>List<T>.min() -> Option<T>List<T>.push(T)List<T>.pop() -> Option<T>List<T>.insert(int, T)List<T>.remove(int) -> TList<T>.reverse()List<T>.clear()List<T>.reserve(int)List<T>.clone() -> List<T>List<T>.slice(int, int) -> List<T>List<T>.sort()List<T>.sort_by(fn(T, T) -> bool)List<T>.sort_by_key(fn(T) -> int)List<T>.join(string) -> stringReading. len and is_empty report the count. first, last, and get(i)
return an Option<T>, none when the index is out of range. contains(x) and
index_of(x) need T to implement Eq. max and min need T to implement
Order.
Bracket read list[i] panics if i is out of range. Use get(i) when you want
an Option instead:
let x: int = nums[0] // panics if emptymatch nums.get(5) { some(v) => io.println("{v}"), none => io.println("no item there"),}Changing. push adds at the end. pop removes and returns the last item as an
Option<T>. insert(i, v) shifts later items down. remove(i) removes and returns
the item at i, panics if i is out of range, and consumes the item. reverse
reverses in place, clear empties the list, and reserve(cap) makes room for
cap items without changing the length. Bracket assign list[i] = v writes item
i.
Copying and slicing. clone() makes a full copy and needs T to implement
Clone and not be move-only. slice(from, to) returns a fresh list with the items
in [from, to) and panics if the range is out of bounds.
There is no new view type or syntax. A normal for loop over a stable List
borrows its existing storage when the compiler proves that the loop cannot
change the list and the item binding cannot escape. Loops that can mutate the
source keep the old snapshot behavior. A temporary slice(...) used only by an
immediate read-only loop or consumer may be fused away; storing or returning the
slice still makes the independent list promised by this API.
Sorting. sort() needs T to implement Order. sort_by takes a strict
less-than predicate; sort_by_key sorts by an integer key computed once per item.
All three sorts are stable: equal items keep their original order.
var words: List<string> = ["pear", "fig", "apple"]words.sort_by_key(fn(w: string) -> int { return w.len() })Joining. join(sep) joins a List<string> into one string with sep between
items:
let csv: string = ["a", "b", "c"].join(",")// "a,b,c"A small program that builds, sorts, and reads a list:
import std.io
fn main() { var nums: List<int> = [3, 1, 2] nums.push(4) nums.sort() io.println("{nums} has {nums.len()} items")
match nums.first() { some(v) => io.println("smallest is {v}"), none => io.println("empty"), } io.println("contains 2: {nums.contains(2)}")}Map<K, V> and OrderedMap<K, V>
Section titled “Map<K, V> and OrderedMap<K, V>”Both store values under keys, and the key type K must implement Eq and Hash.
Maphas no iteration order.OrderedMapkeeps the order in which you inserted keys.
Iterate over keys and values together without making a list or repeating a map lookup:
for name: string, age: int in ages { io.println("{name}: {age}")}This direct loop is O(n) and allocation-free. It follows insertion order for an
OrderedMap. Adding or removing entries during the loop panics before the next
entry is read. Replacing the value of an existing key is allowed.
They share the same methods. Write a map literal with braces; the empty map is
{}:
let ages: Map<string, int> = {"ann": 30, "ben": 25}let empty: Map<string, int> = {}Map<K, V>.get(K) -> Option<V>Map<K, V>.set(K, V)Map<K, V>.insert(K, V) -> boolMap<K, V>.contains_key(K) -> boolMap<K, V>.remove(K) -> boolMap<K, V>.keys() -> List<K>Map<K, V>.values() -> List<V>Map<K, V>.len() -> intMap<K, V>.clear()Map<K, V>.reserve(int)Map<K, V>.clone() -> Map<K, V>OrderedMap<K, V>.get(K) -> Option<V>OrderedMap<K, V>.set(K, V)OrderedMap<K, V>.insert(K, V) -> boolOrderedMap<K, V>.contains_key(K) -> boolOrderedMap<K, V>.remove(K) -> boolOrderedMap<K, V>.keys() -> List<K>OrderedMap<K, V>.values() -> List<V>OrderedMap<K, V>.len() -> intOrderedMap<K, V>.clear()OrderedMap<K, V>.reserve(int)OrderedMap<K, V>.clone() -> OrderedMap<K, V>get(k)returnsOption<V>,nonewhen the key is missing.set(k, v)writes the value underk, replacing any old one; the same asm[k] = v.insert(k, v)writes only whenkis new, and returnsfalsewithout changing anything when the key already exists.contains_key(k)tests for a key.remove(k)deletes it and returnstruewhen the key was present.keys()andvalues()return lists in the map’s iteration order.lencounts the pairs,clearempties the map, andreserve(cap)makes room forcappairs.clone()makes a full copy and needs bothKandVto implementClone.
Bracket read map[key] panics if the key is missing. Use get(key) for an
Option.
import std.io
fn main() { var ages: Map<string, int> = {"ann": 30} ages.set("ben", 25)
let added: bool = ages.insert("ann", 99) io.println("insert added a new key: {added}")
match ages.get("ben") { some(age) => io.println("ben is {age}"), none => io.println("no ben"), }
for name: string, age: int in ages { io.println("{name}: {age}") } io.println("{ages.len()} people")}See also
Section titled “See also”- The memory model, move-only handles and
move. - Option, Result, and Error, the return type of
get,pop,first. - string,
splitreturns aList<string>.