Collections
Building immutable collections
Mutable collections can start out empty and be built up.
This doesn't work for immutable collections.
Below are the ways to initialize immutable collections, starting with the simplest:
- Using
neworlist-new. See "new" functions. - Using
fororfor*loop. See Iteration. - Using
build. This exposes abuilderwhich is used to add elements one at a time.
There is no way to inspect the elements in abuilderuntil it's finished. - Using a
mut-array, then callingmove-toat the end. This is the most flexible approach.
To demonstrate each method:
All of these methods can also be used to initialize mutable collections.
Arrays
Array views
An array-view is a slice of an original array.
It has similar functionality to an array, but with different performance.
Using an array-view avoids copying the array elements,
but holds onto the entire original array even if only viewing a small part.
It also adds a level of indirection.
You should usually use arrays and only use a view when there is a clear advantage.
There are two ways to get an array-view:
- An
arraycan implicitly convert to anarray-view. - Slicing an array returns an
array-view:a[2..5]"
Slicing can also index relative to the array size, such as
a[1 .. end]
which is equivalent to
a[1 .. a.size] .
To slice an array and get another array, use to.
Collection conversion
Most collections define at least two to functions:
one converting to an array and one converting from an array.
This makes it possible to convert between any two collections by going through an array.
To convert to another collection while emptying the original collection,
there is often a move-to function.
Mutable arrays
Buffers
A buffer is like an array with mutable elements, but unlike a mut-array, it is fixed in size.
buffers aren't common, but are useful for low-level code.
For example, mut-array is implemented using a buffer.
Low-level buffer use typically uses uninitialized-buffer,
which is unsafe. (See Unsafe code.)
A buffer-view works like an array-view.
Writing to a buffer-view affects the original buffer.
Maps
A map is a collection of (key, value) pairs with unique keys
that supports efficiently getting a value from the key.
The key must satisfy the key spec, which means
==, <=>, and hash must be defined for it.
A map type is written as value[key],
equivalent to (key, value) map.
Map lookup uses the same subscript syntax as for arrays.
Unlike for an array, it returns an option instead of throwing an exception on a missing key.
A map is constructed from a collection of tuples and iterates as tuples too.
If the map key is symbol, it can be created with named-new syntax.
Map iteration
Maps are designed for efficient lookups. To accomplish this, they internally use hashing.
Hashing depends on a random seed.
This makes it unsafe to expose to safe code (which should not behave randomly).
To keep it safe, map iteration sorts the map first.
If you will need to iterate a map frequently, consider using a sorted-map.
This has the same functions as map but is always kept sorted, making iteration fast.
The cost is that sorted-map is slower to look up keys than map.
If you need both fast iteration and the fastest possible lookups,
you could call unsorted before iterating the map.
This is unsafe. (That will be explained in Unsafe code.)
Mutable maps
A mutable map is written as value mut[key],
equivalent to (key, value) mut-map.
Like with map, there is a mut-sorted-map that iterates faster at the expense of slower lookups.
Other collections
There are other collections in the standard library.
Each has immutable and mutable versions.
There are also shared collections, which will be explained in Parallelism.
| Name | Use |
|---|---|
counter, mut-counter | Tracks how many of each value it contains. |
deque, mut-deque | Fast to push or pop to/from either end. |
priority-queue, mut-priority-queue | (key, value) pairs sorted by key, with fast removal of the least key. |
set, mut-set | Stores only unique values, with fast test for inclusion. |
sorted-set, mut-sorted-set | set with slower lookups but fast iteration. |
stack, mut-stack | Fast to push or pop to/from the right. |
queue, mut-queue | Fast to push to the right or pop from the left. |