Class Map

A map from key objects to values.
The objects used as keys must have a hash-code method that returns an integer that does not change while the object is in the map.
The == operator should be compatible with the hash-code method so that objects that test equal also have the same hash code. However, objects that test unequal are not required to have different hash codes: Hash code clashes are allowed, but should be rare to maintain good performance.
Strings, byte arrays, and numbers fulfill these requirements and can be used as keys in maps.

Class summary


constructor
Constructs an empty map.
constructor size/any [get-key] [get-value]
Constructs a Map with a given size.

Constructors

Constructs an empty map.

constructor size/any [get-key] [get-value]
Constructs a Map with a given size.
For each key-value pair, first the block get-key and then the block get-value are called.

Statics

Constructs a weak map where the values may be replaced by null when there is memory pressure.
A cleanup task may remove keys whose values are null at some later point, but your program should not rely on this. This cleanup task will also remove key-value pairs where the value was deliberately set to null.

Methods

any --keys/True [predicate] -> bool
Whether at least one key in the map satisfies the given predicate.
Returns false, if the map is empty.

any --values/True [predicate] -> bool
Whether at least one value in the map satisfies the given predicate.
Returns false, if the map is empty.

any [predicate] -> bool
Whether at least one key-value pair in the map satisfies the given predicate.
The predicate block is called with two arguments: a key, and its value.
Returns false, if the map is empty.

clear -> none
Removes all elements from this instance.

contains key/any -> bool
Whether this instance contains the given key.

Whether this instance contains all elements of collection.

Copies the map.
The copy is shallow.

do [block] -> none
Invokes the given block on each key/value pair of this instance.
The key/value pairs are iterated in key insertion order.
Users must not modify this instance while iterating over it.

do --reversed/True [block] -> none
Variant of do [block].
Iterates over all key/value pairs in reverse order.
Users must not modify this instance while iterating over it.

do --keys/True --reversed/bool=false [block] -> none
Invokes the given block on each key of this instance.
Users must not modify this instance while iterating over it.

do --values/True --reversed/bool=false [block] -> none
Invokes the given block on each value of this instance.
Users must not modify this instance while iterating over it.

every --keys/True [predicate] -> bool
Whether all keys in the map satisfy the given predicate.
Returns true, if the map is empty.

every --values/True [predicate] -> bool
Whether all values in the map satisfy the given predicate.
Returns true, if the map is empty.

every [predicate] -> bool
Whether all key-value pairs in the map satisfy the given predicate.
The predicate block is called with two arguments: a key, and its value.
Returns true, if the map is empty.

filter --in-place/bool=false [predicate] -> Map
Filters this instance using the given predicate.
Returns this instance if in-place is true. In this case removes the elements that don't match the predicate.
Returns a new map if in-place is false (the default).
The result contains all the elements of this instance for which the predicate returns true.
Users must not otherwise modify this instance during the operation.

first -> any
The first key of the map by insertion order.
Throws an error if the map is empty.

get key/any -> any
Retrieves the value for key.
Returns the value verbatim, if the key is contained in the map.
Returns null, otherwise.

get key/any [--if-absent] -> any
Retrieves the value for key.
Returns the value verbatim, if this instance contains the key.
Otherwise, calls if-absent with the key and returns the result of the call.

get key/any [--if-present] -> any
Retrieves the value for key.
If this instance contains the key calls if-present with the corresponding value and returns the result.
Returns null otherwise.

get key/any [--if-present] [--if-absent] -> any
Retrieves the value for key.
If this instance contains the key calls if-present with the corresponding value and returns the result.
Otherwise, calls if-absent with the key and returns the result of the call.

get key/any [--init] -> any
Retrieves the value for key.
Returns the value verbatim, if this instance contains the key.
Otherwise, initializes the slot with the result of calling init first.

Whether this instance is empty.

Returns the keys of this instance as a list.
This operation instantiates a fresh list and is thus in O(n).
When possible use do --keys [block] instead.

last -> any
The last key of the map by insertion order.
Throws an error if the map is empty.

map [block] -> Map
Invokes the given block on each key/value pair and returns a new map with the results.
The block is invoked with two arguments for each entry in this instance: the key and the value. The returned value becomes the new value for the key.
Examples

map := { "a": 1, "b": 2 }

// Double the values. (Key is not used).
doubled := map.map: | _ value | value * 2
print doubled  // => { "a": 2, "b": 4 }

// Prefix the values with the key.
prefixed := map.map: | key value | "$key-$value"
print prefixed  // => { "a": "a-1", "b": "b-2" }

map --in-place/True [block] -> none
Maps the values of this instance.
Invokes the given block on each key/value pair and replaces the old value with the result of the call.

operator [] key/any -> any
Returns the element stored at location key.
The key must be in the map.

operator []= key/any value/any -> any
Stores value in the location for the given key.
If the key is already present, overrides the previous value.

operator == other/any -> bool
Whether this object is equal to the other.
By default, identical is used for equality.
Inheritance
Classes overwrite this operator to get an equality specific to their needs. Equality operators often compare the type and field contents. For example:

class Pin:
  number/int

  constructor .number:

  operator == other:
    if other is not Pin: return false
    return number == other.number
A class doesn't have to follow the above format, but it must keep the operator in sync with any hash-code method. That is, if a class has a hash-code member, then the equality and hash-code must agree. If two instances are equal (a == b), then their hash codes must also be equal (a.hash-code == b.hash-code).

reduce --values/True [block] -> any
Reduces the values of the map into a single value.

reduce --values/True --initial/any [block] -> any
Reduces the values of the map into a single value.

reduce --keys/True [block] -> any
Reduces the keys of the map into a single value.

reduce --keys/True --initial/any [block] -> any
Reduces the keys of the map into a single value.

reduce --initial/any [block] -> any
Reduces the map entries into a single value.
The given block is called with three arguments: 1. the accumulated result, so far 2. the key of the current entry 3. the value of the current entry.

remove key/any [--if-absent] -> none
Removes the given key from this instance.
If the key is absent, calls if-absent with the key.

remove key/any -> none
Removes the given key from this instance.
The key does not need to be present.

remove-all collection/Collection -> none
Removes all elements of collection from this instance.

The number of elements in this instance.

update key/any [updater] -> any
Updates the value of the given key.
Calls the updater with the current value, and replaces the old value with the result.
Returns the result of calling the updater.
This instance must contain the key.

update key/any [updater] [--if-absent] -> any
Updates the value of the given key.
If this instance contains the key, calls the updater with the current value, and replaces the old value with the result. Returns the result of the call.
If this instance does not contain the key, calls if-absent with the key instead, and stores the result of the call in this instance. Returns the result of the call.

update key/any [updater] --if-absent/any -> any
Updates the value of the given key.
If this instance contains the key, calls the updater with the current value, and replaces the old value with the result. Returns the result of the call.
If this instance does not contain the key, stores if-absent in this instance. Returns if-absent.

update key/any [--init] [updater] -> any
Updates the value of the given key.
If this instance does not contain the key, calls init with the key first, and stores it in this instance.
Calls the updater with the current value (which might be the initial value that was just stored) and replaces the old value with the result.
Returns the result of the call to the updater.

update key/any --init/any [updater] -> any
Updates the value of the given key.
If this instance does not contain the key, stores init in this instance.
Calls the updater with the current value (which might be the initial value that was just stored) and replaces the old value with the result.
Returns the result of the call to the updater.

Returns the values of this instance as a list.
This operation instantiates a fresh list and is thus in O(n).
When possible use do --values [block] instead.