PersistentMap<K, V> abstract class
An immutable map, binding keys of type K to values of type V. Null values are supported but null keys are not.
In all the examples below {k1: v1, k2: v2, ...}
is a shorthand for
PersistentMap.fromMap({k1: v1, k2: v2, ...})
.
abstract class PersistentMap<K, V> implements Iterable<Pair<K, V>> { /** Creates an empty [PersistentMap] using its default implementation. */ factory PersistentMap() => new _EmptyMap<K, V>(); /** * Creates an immutable copy of [map] using the default implementation of * [PersistentMap]. */ factory PersistentMap.fromMap(Map<K, V> map) { PersistentMap<K, V> result = new _EmptyMap<K, V>(); map.forEach((K key, V value) { result = result.insert(key, value); }); return result; } /** * Returns a new map identical to `this` except that it binds [key] to * [value]. * * If [key] was bound to some `oldvalue` in `this`, it is nevertheless bound * to [value] in the new map. If [key] was bound to some `oldvalue` in `this` * and if [combine] is provided then [key] it is bound to * `combine(oldvalue, value)` in the new map. * * {'a': 1}.insert('b', 2) == {'a': 1, 'b', 2} * {'a': 1, 'b': 2}.insert('b', 3) == {'a': 3, 'b', 3} * {'a': 1, 'b': 2}.insert('b', 3, (x,y) => x - y) == {'a': 3, 'b', -1} */ PersistentMap<K, V> insert(K key, V value, [V combine(V oldvalue, V newvalue)]); /** * Returns a new map identical to `this` except that it doesn't bind [key] * anymore. * * {'a': 1, 'b': 2}.delete('b') == {'a': 1} * {'a': 1}.delete('b') == {'a': 1} */ PersistentMap<K, V> delete(K key); /** * Looks up the value possibly bound to [key] in `this`. Returns * `Option.some(value)` if it exists, `Option.none()` otherwise. * * {'a': 1}.lookup('b') == Option.none() * {'a': 1, 'b': 2}.lookup('b') == Option.some(2) */ Option<V> lookup(K key); /** * Evaluates `f(key, value)` for each (`key`, `value`) pair in `this`. */ void forEachKeyValue(f(K key, V value)); /** * Returns a new map identical to `this` except that the value it possibly * binds to [key] has been adjusted by [update]. * * {'a': 1, 'b': 2}.adjust('b', (x) => x + 1) == {'a', 1, 'b', 3} * {'a': 1}.adjust('b', (x) => x + 1) == {'a', 1} */ PersistentMap<K, V> adjust(K key, V update(V value)); /** * Returns a new map identical to `this` where each value has been updated by * [f]. * * {'a': 1, 'b': 2}.mapValues((x) => x + 1) == {'a', 2, 'b', 3} * {}.mapValues((x) => x + 1) == {} */ PersistentMap mapValues(f(V value)); /** * Returns a new map whose (key, value) pairs are the union of those of `this` * and [other]. * * The union is right-biased: if a key is present in both `this` and [other], * the value from [other] is retained. If [combine] is provided, the retained * value for a `key` present in both `this` and [other] is then * `combine(leftvalue, rightvalue)` where `leftvalue` is the value bound to * `key` in `this` and `rightvalue` is the one bound to `key` in [other]. * * {'a': 1}.union({'b': 2}) == {'a': 1, 'b': 2} * {'a': 1}.union({'a': 3, 'b': 2}) == {'a': 3, 'b': 2} * {'a': 1}.union({'a': 3, 'b': 2}, (x,y) => x + y) == {'a': 4, 'b': 2} * * Note that [union] is commutative if and only if [combine] is provided and * if it is commutative. */ PersistentMap<K, V> union(PersistentMap<K, V> other, [V combine(V left, V right)]); /** * Returns a new map whose (key, value) pairs are the intersection of those of * `this` and [other]. * * The intersection is right-biased: values from [other] are retained. If * [combine] is provided, the retained value for a `key` present in both * `this` and [other] is then `combine(leftvalue, rightvalue)` where * `leftvalue` is the value bound to `key` in `this` and `rightvalue` is the * one bound to `key` in [other]. * * {'a': 1}.intersection({'b': 2}) == {} * {'a': 1}.intersection({'a': 3, 'b': 2}) == {'a': 3} * {'a': 1}.intersection({'a': 3, 'b': 2}, (x,y) => x + y) == {'a': 4} * * Note that [intersection] is commutative if and only if [combine] is * provided and if it is commutative. */ PersistentMap<K, V> intersection(PersistentMap<K, V> other, [V combine(V left, V right)]); /// Returns a mutable copy of `this`. Map<K, V> toMap(); /// The keys of `this`. Iterable<K> get keys; /// The values of `this`. Iterable<V> get values; /// Randomly picks an entry of `this`. Pair<K, V> pickRandomEntry([Random random]); }
Subclasses
Implements
Constructors
factory PersistentMap() #
Creates an empty PersistentMap using its default implementation.
factory PersistentMap() => new _EmptyMap<K, V>();
factory PersistentMap.fromMap(Map<K, V> map) #
Creates an immutable copy of map using the default implementation of PersistentMap.
factory PersistentMap.fromMap(Map<K, V> map) { PersistentMap<K, V> result = new _EmptyMap<K, V>(); map.forEach((K key, V value) { result = result.insert(key, value); }); return result; }
Properties
final E first #
Returns the first element.
If this
is empty throws a StateError. Otherwise this method is
equivalent to this.elementAt(0)
E get first;
final bool isEmpty #
Returns true if there is no element in this collection.
bool get isEmpty;
final bool isNotEmpty #
Returns true if there is at least one element in this collection.
bool get isNotEmpty;
final Iterator<E> iterator #
Returns an Iterator that iterates over this Iterable object.
Iterator<E> get iterator;
final int length #
Returns the number of elements in this
.
Counting all elements may be involve running through all elements and can therefore be slow.
int get length;
final E single #
Returns the single element in this
.
If this
is empty or has more than one element throws a StateError.
E get single;
Methods
abstract PersistentMap<K, V> adjust(K key, V update(V value)) #
Returns a new map identical to this
except that the value it possibly
binds to
key has been adjusted by
update.
{'a': 1, 'b': 2}.adjust('b', (x) => x + 1) == {'a', 1, 'b', 3}
{'a': 1}.adjust('b', (x) => x + 1) == {'a', 1}
abstract bool any(bool test(E element)) #
Returns true if one element of this collection satisfies the predicate test. Returns false otherwise.
abstract bool contains(Object element) #
Returns true if the collection contains an element equal to element.
abstract PersistentMap<K, V> delete(K key) #
Returns a new map identical to this
except that it doesn't bind
key
anymore.
{'a': 1, 'b': 2}.delete('b') == {'a': 1}
{'a': 1}.delete('b') == {'a': 1}
abstract E elementAt(int index) #
Returns the indexth element.
If this
has fewer than
index elements throws a RangeError.
Note: if this
does not have a deterministic iteration order then the
function may simply return any element without any iteration if there are
at least
index elements in this
.
abstract bool every(bool test(E element)) #
Returns true if every elements of this collection satisify the
predicate
test. Returns false
otherwise.
abstract E firstWhere(bool test(E element), {E orElse()}) #
Returns the first element that satisfies the given predicate test.
If none matches, the result of invoking the
orElse function is
returned. By default, when
orElse is null
, a StateError is
thrown.
abstract dynamic fold(initialValue, combine(previousValue, E element)) #
Reduces a collection to a single value by iteratively combining each element of the collection with an existing value using the provided function.
Use initialValue as the initial value, and the function combine to create a new value from the previous one and an element.
Example of calculating the sum of an iterable:
iterable.fold(0, (prev, element) => prev + element);
abstract void forEach(void f(E element)) #
Applies the function f to each element of this collection.
abstract void forEachKeyValue(f(K key, V value)) #
Evaluates f(key, value)
for each (key
, value
) pair in this
.
abstract PersistentMap<K, V> insert(K key, V value, [V combine(V oldvalue, V newvalue)]) #
Returns a new map identical to this
except that it binds
key to
value.
If
key was bound to some oldvalue
in this
, it is nevertheless bound
to
value in the new map. If
key was bound to some oldvalue
in this
and if
combine is provided then
key it is bound to
combine(oldvalue, value)
in the new map.
{'a': 1}.insert('b', 2) == {'a': 1, 'b', 2}
{'a': 1, 'b': 2}.insert('b', 3) == {'a': 3, 'b', 3}
{'a': 1, 'b': 2}.insert('b', 3, (x,y) => x - y) == {'a': 3, 'b', -1}
abstract PersistentMap<K, V> intersection(PersistentMap<K, V> other, [V combine(V left, V right)]) #
Returns a new map whose (key, value) pairs are the intersection of those of
this
and
other.
The intersection is right-biased: values from
other are retained. If
combine is provided, the retained value for a key
present in both
this
and
other is then combine(leftvalue, rightvalue)
where
leftvalue
is the value bound to key
in this
and rightvalue
is the
one bound to key
in
other.
{'a': 1}.intersection({'b': 2}) == {}
{'a': 1}.intersection({'a': 3, 'b': 2}) == {'a': 3}
{'a': 1}.intersection({'a': 3, 'b': 2}, (x,y) => x + y) == {'a': 4}
Note that intersection is commutative if and only if combine is provided and if it is commutative.
String join([String separator = ""]) #
Converts each element to a String and concatenates the strings.
Converts each element to a String by calling Object.toString on it. Then concatenates the strings, optionally separated by the separator string.
String join([String separator = ""]) { StringBuffer buffer = new StringBuffer(); buffer.writeAll(this, separator); return buffer.toString(); }
abstract E lastWhere(bool test(E element), {E orElse()}) #
Returns the last element that satisfies the given predicate test.
If none matches, the result of invoking the
orElse function is
returned. By default, when
orElse is null
, a StateError is
thrown.
abstract Option<V> lookup(K key) #
Looks up the value possibly bound to
key in this
. Returns
Option.some(value)
if it exists, Option.none()
otherwise.
{'a': 1}.lookup('b') == Option.none()
{'a': 1, 'b': 2}.lookup('b') == Option.some(2)
abstract Iterable map(f(E element)) #
Returns a lazy Iterable where each element e
of this
is replaced
by the result of f(e)
.
This method returns a view of the mapped elements. As long as the returned Iterable is not iterated over, the supplied function f will not be invoked. The transformed elements will not be cached. Iterating multiple times over the the returned Iterable will invoke the supplied function f multiple times on the same element.
abstract PersistentMap mapValues(f(V value)) #
Returns a new map identical to this
where each value has been updated by
f.
{'a': 1, 'b': 2}.mapValues((x) => x + 1) == {'a', 2, 'b', 3}
{}.mapValues((x) => x + 1) == {}
abstract E reduce(E combine(E value, E element)) #
Reduces a collection to a single value by iteratively combining elements of the collection using the provided function.
Example of calculating the sum of an iterable:
iterable.reduce((value, element) => value + element);
abstract E singleWhere(bool test(E element)) #
Returns the single element that satisfies test. If no or more than one element match then a StateError is thrown.
abstract Iterable<E> skip(int n) #
Returns an Iterable that skips the first n elements.
If this
has fewer than
n elements, then the resulting Iterable is
empty.
It is an error if n is negative.
abstract Iterable<E> skipWhile(bool test(E value)) #
Returns an Iterable that skips elements while test is satisfied.
The filtering happens lazily. Every new Iterator of the returned
Iterable iterates over all elements of this
.
As long as the iterator's elements satisfy
test they are
discarded. Once an element does not satisfy the
test the iterator stops
testing and uses every later element unconditionally. That is, the elements
of the returned Iterable are the elements of this
starting from the
first element that does not satisfy
test.
abstract Iterable<E> takeWhile(bool test(E value)) #
Returns an Iterable that stops once test is not satisfied anymore.
The filtering happens lazily. Every new Iterator of the returned
Iterable starts iterating over the elements of this
.
When the iterator encounters an element e
that does not satisfy
test,
it discards e
and moves into the finished state. That is, it does not
get or provide any more elements.
abstract PersistentMap<K, V> union(PersistentMap<K, V> other, [V combine(V left, V right)]) #
Returns a new map whose (key, value) pairs are the union of those of this
and
other.
The union is right-biased: if a key is present in both this
and
other,
the value from
other is retained. If
combine is provided, the retained
value for a key
present in both this
and
other is then
combine(leftvalue, rightvalue)
where leftvalue
is the value bound to
key
in this
and rightvalue
is the one bound to key
in
other.
{'a': 1}.union({'b': 2}) == {'a': 1, 'b': 2}
{'a': 1}.union({'a': 3, 'b': 2}) == {'a': 3, 'b': 2}
{'a': 1}.union({'a': 3, 'b': 2}, (x,y) => x + y) == {'a': 4, 'b': 2}
Note that union is commutative if and only if combine is provided and if it is commutative.
abstract Iterable<E> where(bool test(E element)) #
Returns a lazy Iterable with all elements that satisfy the predicate test.
This method returns a view of the mapped elements. As long as the returned Iterable is not iterated over, the supplied function test will not be invoked. Iterating will not cache results, and thus iterating multiple times over the returned Iterable will invoke the supplied function test multiple times on the same element.