Advanced Collections
Tova provides specialized collection types in the collections namespace for common data structure patterns beyond arrays and objects.
Constructor Syntax
Use Type.new() to construct these types (e.g., OrderedDict.new(), Counter.new(items)). The collections.Type() namespace syntax is not yet supported.
OrderedDict
An insertion-ordered dictionary that maintains the order in which keys were added.
d = OrderedDict.new()Methods
set
d.set(key, value) -> OrderedDictSets a key-value pair. If the key exists, updates the value without changing order.
var d = OrderedDict.new()
d = d.set("b", 2)
d = d.set("a", 1)
d = d.set("c", 3)get
d.get(key) -> T | NilReturns the value for a key, or nil if not found.
d.get("a") // 1
d.get("z") // nildelete
d.delete(key) -> OrderedDictRemoves a key-value pair.
d = d.delete("b") // requires var d from initial declarationhas
d.has(key) -> BoolReturns true if the key exists.
d.has("a") // true
d.has("z") // falsekeys / values / entries
d.keys() -> [String]
d.values() -> [T]
d.entries() -> [[String, T]]Returns keys, values, or entries in insertion order.
d.keys() // ["b", "a", "c"]
d.values() // [2, 1, 3]
d.entries() // [["b", 2], ["a", 1], ["c", 3]]length
d.length -> IntThe number of entries.
DefaultDict
A dictionary that returns a default value for missing keys, generated by a factory function.
d = DefaultDict.new(fn() 0)Constructor
DefaultDict.new(factory) -> DefaultDictThe factory is a function that produces the default value when a missing key is accessed.
// Counter pattern
counter = DefaultDict.new(fn() 0)
// List accumulator pattern
groups = DefaultDict.new(fn() [])Methods
get
d.get(key) -> TReturns the value for a key. If the key does not exist, calls the factory, stores the result, and returns it.
counter = DefaultDict.new(fn() 0)
counter.get("apples") // 0 (created by factory)
counter.set("apples", counter.get("apples") + 1)
counter.get("apples") // 1set
d.set(key, value) -> DefaultDictSets a key-value pair.
delete
d.delete(key) -> DefaultDictRemoves a key-value pair.
has
d.has(key) -> BoolReturns true if the key exists (without triggering the factory).
Counter
A specialized collection for counting occurrences of items. Pass an iterable to the constructor to count items.
c = Counter.new(["apple", "banana", "apple"])Methods
count
c.count(item) -> IntReturns the count for an item, or 0 if not found. Items are counted by passing an array to the constructor.
c = Counter.new(["apple", "banana", "apple"])
c.count("apple") // 2
c.count("banana") // 1
c.count("cherry") // 0total
c.total() -> IntReturns the sum of all counts.
c.total() // 3most_common
c.most_common(n?) -> [[T, Int]]Returns the n most common items and their counts, sorted by frequency. If n is omitted, returns all items.
c.most_common() // [["apple", 2], ["banana", 1]]
c.most_common(1) // [["apple", 2]]keys / values / entries
c.keys() -> [T]
c.values() -> [Int]
c.entries() -> [[T, Int]]Returns items, counts, or item-count pairs.
Deque
A double-ended queue supporting efficient insertion and removal at both ends.
dq = Deque.new()Methods
push_back / push_front
dq.push_back(value) -> Deque
dq.push_front(value) -> DequeAdds a value to the back or front.
var dq = Deque.new()
dq = dq.push_back(1)
dq = dq.push_back(2)
dq = dq.push_front(0)
// [0, 1, 2]pop_back / pop_front
dq.pop_back() -> [T | Nil, Deque]
dq.pop_front() -> [T | Nil, Deque]Returns a two-element array: the removed value (or nil if empty) and a new Deque without that element. Does not mutate the original.
[val, rest] = dq.pop_front() // val = 0, rest = Deque([1, 2])
[val2, rest2] = dq.pop_back() // val2 = 2, rest2 = Deque([0, 1])peek_back / peek_front
dq.peek_back() -> T | Nil
dq.peek_front() -> T | NilReturns the value at the back or front without removing it.
length
dq.length -> IntThe number of elements.
toArray
dq.toArray() -> [T]Converts the deque to an array.
var dq = Deque.new()
dq = dq.push_back(1)
dq = dq.push_back(2)
dq = dq.push_back(3)
dq.toArray() // [1, 2, 3]Examples
Word Frequency Counter
text = "the cat sat on the mat the cat"
counter = Counter.new(words(text))
counter.most_common(3)
// [["the", 3], ["cat", 2], ["sat", 1]]Task Queue with Deque
var queue = Deque.new()
queue = queue.push_back("task1")
queue = queue.push_back("task2")
queue = queue.push_front("urgent-task")
loop {
task, queue = queue.pop_front()
if task == nil { break }
process(task)
}Grouping with DefaultDict
groups = DefaultDict.new(fn() [])
for user in users {
items = groups.get(user.role)
groups.set(user.role, [...items, user])
}