import type { RSet } from '@rimbu/collection-types'; import type { KeyValue, WithKeyValue, } from '@rimbu/collection-types/map-custom'; import type { ArrayNonEmpty, RelatedTo, ToJSON, TraverseState, } from '@rimbu/common'; import type { MultiMap } from '@rimbu/multimap'; import type { FastIterable, Reducer, Stream, StreamSource, Streamable, } from '@rimbu/stream'; export interface BiMultiMapBase< K, V, Tp extends BiMultiMapBase.Types = BiMultiMapBase.Types, > extends FastIterable<[K, V]> { /** * Returns the `context` associated to this collection instance. */ readonly context: WithKeyValue['context']; /** * Returns the MultiMap representation of the key to value mapping. * @example * ```ts * HashBiMultiMap.of([1, 10], [1, 20]).keyValueMultiMap.toArray() * // => [[1, [10, 20]] * ``` */ readonly keyValueMultiMap: WithKeyValue['keyValueMultiMap']; /** * Returns the MultiMap representation of the value to key mapping. * @example * ```ts * HashBiMultiMap.of([10, 1], [20, 1]).valueKeyMultiMap.toArray() * // => [[1, [10, 20]] * ``` */ readonly valueKeyMultiMap: WithKeyValue['valueKeyMultiMap']; /** * Returns true if the collection is empty. * @example * ```ts * HashBiMultiMap.empty().isEmpty // => true * HashBiMultiMap.of([1, 1], [2, 2]).isEmpty // => false * ``` */ readonly isEmpty: boolean; /** * Returns the number of keys * @example * ```ts * HashBiMultiMap.of([1, 10], [1, 20]).keySize // => 1 * ``` */ readonly keySize: number; /** * Returns the number of entries * @example * ```ts * HashBiMultiMap.of([1, 10], [2, 10]).size // => 2 * ``` */ readonly size: number; /** * Returns a `Stream` containing all entries of this collection as tuples of key and value. * @example * ```ts * HashBiMultiMap.of([1, 10], [1, 20]).stream().toArray() // => [[1, 10], [1, 20]] * ``` */ stream(): Stream<[K, V]>; /** * Returns a `Stream` containing all keys of this collection. * @example * ```ts * HashBiMultiMap.of([[1, 'a'], [2, 'b']]).streamKeys().toArray() // => [1, 2] * ``` */ streamKeys(): Stream; /** * Returns a `Stream` containing all values of this collection. * @example * ```ts * HashBiMultiMap.of([[1, 'a'], [2, 'b']]).streamValues().toArray() // => ['a', 'b'] * ``` */ streamValues(): Stream; /** * Returns the collection as a .NonEmpty type * @throws RimbuError.EmptyCollectionAssumedNonEmptyError if the collection is empty * @example * ```ts * HashBiMultiMap.empty().assumeNonEmpty() // => throws * const m: HashBiMultiMap = HashBiMultiMap.of([1, 1], [2, 2]) * const m2: HashBiMultiMap.NonEmpty = m // => compiler error * const m3: HashBiMultiMap.NonEmpty = m.assumeNonEmpty() * ``` * @note returns reference to this collection */ assumeNonEmpty(): WithKeyValue['nonEmpty']; /** * Returns true if there is at least one entry in the collection, and instructs the compiler to treat the collection * as a .NonEmpty type. * @example * ```ts * const m: HashBiMultiMap = HashBiMultiMap.of([1, 1], [2, 2]) * m.stream().first(0) // compiler allows fallback value since the Stream may be empty * if (m.nonEmpty()) { * m.stream().first(0) // compiler error: fallback value not allowed since Stream is not empty * } * ``` */ nonEmpty(): this is WithKeyValue['nonEmpty']; /** * Returns true if the given `key` is present in the collection. * @param key - the key to look for * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']) * m.hasKey(2) // => true * m.hasKey(3) // => false * ``` */ hasKey(key: RelatedTo): boolean; /** * Returns true if the given `value` is present in the collection. * @param value - the value to look for * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']) * m.hasKey('a') // => true * m.hasKey('z') // => false * ``` */ hasValue(key: RelatedTo): boolean; /** * Returns true if the given key and value entry is in the collection. * @param key - the entry key to look for * @param value - the entry value to look for * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']) * m.hasEntry(2, 'b') // => true * m.hasEntry(2, 'c') // => false * ``` */ hasEntry( key: RelatedTo, value: RelatedTo ): boolean; /** * Returns the collection with the given `key` associated to the given `value`. * @param key - the entry key to add * @param value - the entry value to add * @example * ```ts * HashBiMultiMap.of([1, 1], [2, 2]).add(1, 2).toArray() * // => [[1, 1], [1, 2], [2, 2]] * ``` */ add(key: K, value: V): WithKeyValue['nonEmpty']; /** * Returns the collection with the entries from the given `StreamSource` `entries` added. * @param entries - a `StreamSource` containing tuples with a key and value * @example * ```ts * HashBiMultiMap.of([1, 1]).addEntries([[2, 2], [1, 3]]).toArray() * // => [[1, 1], [1, 3], [2, 2]] * ``` */ addEntries( entries: StreamSource.NonEmpty ): WithKeyValue['nonEmpty']; addEntries( entries: StreamSource ): WithKeyValue['normal']; /** * Returns the collection with the values from the given `values` StreamSource associated * with the given `key`. * @param key - the entry key * @param values - a `StreamSource` containing values to associate with the given `key` * @example * ```ts * HashBiMultiMap.of([1, 1]).setValues(1, [2, 3]).toArray() * // => [[1, 1], [1, 2], [1, 3]] * ``` */ setValues( key: K, values: StreamSource.NonEmpty ): WithKeyValue['nonEmpty']; setValues(key: K, values: StreamSource): WithKeyValue['normal']; /** * Returns the collection with the keys from the given `keys` StreamSource associated * with the given `value`. * @param value - the entry value * @param keys - a `StreamSource` containing keys to associate with the given `value` * @example * ```ts * HashBiMultiMap.of([1, 1]).setKeys(1, [2, 3]).toArray() * // => [[1, 1], [2, 1], [3, 1]] * ``` */ setKeys( value: V, keys: StreamSource.NonEmpty ): WithKeyValue['nonEmpty']; setKeys(value: V, keys: StreamSource): WithKeyValue['normal']; /** * Returns a collection containing the values associated with the given `key`. * @param key - the key of which to find the values * @example * ```ts * const m = HashBiMultiMap.of([1, 1], [1, 2]); * m.getValues(1).toArray() * // => [1, 2] * m.getValues(5).toArray() * // => [] * ``` */ getValues( key: RelatedTo ): WithKeyValue['keyMultiMapValues']; /** * Returns a collection containing the keys associated with the given `value`. * @param value - the value of which to find the keys * @example * ```ts * const m = HashBiMultiMap.of([1, 1], [2, 1]); * m.getKeys(1).toArray() * // => [1, 2] * m.getKeys(5).toArray() * // => [] * ``` */ getKeys( value: RelatedTo ): WithKeyValue['valueMultiMapValues']; /** * Returns the collection where the entries associated with given `key` are removed if it was part of the collection. * @param key - the key of the entries to remove * @example * ```ts * const m = HashBiMultiMap.of([1, 1], [1, 2]) * m.removeKey(2).toArray() // => [1, 2] * m.removeKey(3) === m // true * ``` * @note guarantees same object reference if the key is not present */ removeKey(key: RelatedTo): WithKeyValue['normal']; /** * Returns the collection where the entries associated with each key in given `keys` are removed if they were present. * @param keys - a `StreamSource` of keys to remove * @example * ```ts * const m = HashBiMultiMap.of([1, 1], [2, 2]) * m.removeKeys([1, 3]).toArray() // => [[2, 2]] * m.removeKeys([1, 3, 2]).toArray() // => [] * m.removeKeys([3, 4, 5]) === m // => true * ``` * @note guarantees same object reference if none of the keys are present */ removeKeys( keys: StreamSource> ): WithKeyValue['normal']; /** * Returns the collection where the entries associated with given `value` are removed if it was part of the collection. * @param value - the value of the entries to remove * @example * ```ts * const m = HashBiMultiMap.of([1, 2], [2, 2]) * m.removeValue(2).toArray() // => [1, 2] * m.removeValue(3) === m // true * ``` * @note guarantees same object reference if the key is not present */ removeValue( value: RelatedTo ): WithKeyValue['normal']; /** * Returns the collection where the entries associated with each value in given `values` are removed if they were present. * @param values - a `StreamSource` of values to remove * @example * ```ts * const m = HashBiMultiMap.of([1, 1], [2, 2]) * m.removeValues([1, 3]).toArray() // => [[2, 2]] * m.removeValues([1, 3, 2]).toArray() // => [] * m.removeValues([3, 4, 5]) === m // => true * ``` * @note guarantees same object reference if none of the keys are present */ removeValues( values: StreamSource> ): WithKeyValue['normal']; /** * Returns the collection where the entry with given `key` or `value` is removed if present. * @param key - the entry key * @param value - the entry value * @example * ```ts * const m = HashBiMultiMap.of([1, 1], [2, 2]) * m.removeEntry(2, 2).toArray() // => [[1, 1]] * m.removeEntry(1, 2).toArray() // => [[1, 1], [2, 2]] * m.removeEntry(3, 3) === m // => true * ``` */ removeEntry( key: RelatedTo, value: RelatedTo ): WithKeyValue['normal']; /** * Returns the collection where the entries in the given `entries` StreamSource are removed if present. * @param entries - a StreamSource containing entries to remove * @example * ```ts * const m = HashBiMultiMap.of([1, 1], [2, 2]) * m.removeEntries([[2, 2], [2, 3]]).toArray() // => [[1, 1]] * m.removeEntries([[1, 2], [4, 3]]).toArray() // => [[1, 1], [2, 2]] * m.removeEntries([[3, 3]]) === m // => true * ``` */ removeEntries( entries: StreamSource<[RelatedTo, RelatedTo]> ): WithKeyValue['normal']; /** * Performs given function `f` for each entry of the collection, using given `state` as initial traversal state. * @param f - the function to perform for each entry, receiving:
* - `entry`: the next tuple of a key and value
* - `index`: the index of the element
* - `halt`: a function that, if called, ensures that no new elements are passed * @param options - (optional) an object containing the following properties:
* - state: (optional) the traversal state * @example * ```ts * HashBiMultiMap.of([1, 'a'], [2, 'b'], [3, 'c']).forEach((entry, i, halt) => { * console.log([entry[1], entry[0]]); * if (i >= 1) halt(); * }) * // => logs ['a', 1] ['b', 2] * ``` * @note O(N) */ forEach( f: (entry: [K, V], index: number, halt: () => void) => void, options?: { state?: TraverseState } ): void; /** * Returns a collection containing only those entries that satisfy given `pred` predicate. * @param pred - a predicate function receiving:
* - `entry`: the next entry
* - `index`: the entry index
* - `halt`: a function that, when called, ensures no next elements are passed * @param options - (optional) an object containing the following properties:
* - negate: (default: false) when true will negate the given predicate * @example * ```ts * HashBiMultiMap.of([1, 'a'], [2, 'b'], [3, 'c']).filter(entry => entry[0] === 2 || entry[1] === 'c').toArray() * // => [[2, 'b'], [3, 'c']] * ``` */ filter( pred: (entry: [K, V], index: number, halt: () => void) => boolean, options?: { negate?: boolean } ): WithKeyValue['normal']; /** * Returns an array containing all entries in this collection. * @example * ```ts * HashBiMultiMap.of([1, 'a'], [2, 'b']).toArray() // => [[1, 'a'], [2, 'b']] * ``` * @note O(log(N)) */ toArray(): [K, V][]; /** * Returns a string representation of this collection. * @example * ```ts * HashBiMultiMap.of([1, 'a'], [2, 'b']).toString() // => HashBiMultiMap(1 <=> ['a'], 2 <=> ['b']) * ``` */ toString(): string; /** * Returns a JSON representation of this collection. * @example * ```ts * HashBiMultiMap.of([1, 'a'], [2, 'b']).toJSON() // => { dataType: 'HashBiMultiMap', value: [[1, ['a']], [2, ['b']]] } * ``` */ toJSON(): ToJSON<[K, V[]][], this['context']['typeTag']>; /** * Returns a builder object containing the entries of this collection. * @example * ```ts * const builder: HashBiMultiMap.Builder = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * ``` */ toBuilder(): WithKeyValue['builder']; } export namespace BiMultiMapBase { export interface NonEmpty< K, V, Tp extends BiMultiMapBase.Types = BiMultiMapBase.Types, > extends BiMultiMapBase, Streamable.NonEmpty<[K, V]> { /** * Returns the non-empty MultiMap representation of the key to value mapping. * @example * ```ts * HashBiMultiMap.of([1, 10], [1, 20]).keyValueMultiMap.toArray() * // => [[1, [10, 20]] * ``` */ readonly keyValueMultiMap: WithKeyValue< Tp, K, V >['keyValueMultiMapNonEmpty']; /** * Returns the MultiMap representation of the value to key mapping. * @example * ```ts * HashBiMultiMap.of([10, 1], [20, 1]).valueKeyMultiMap.toArray() * // => [[1, [10, 20]] * ``` */ readonly valueKeyMultiMap: WithKeyValue< Tp, K, V >['valueKeyMultiMapNonEmpty']; /** * Returns false since this collection is known to be non-empty. * @example * ```ts * HashBiMultiMap.of([1, 1], [2, 2]).isEmpty // => false * ``` */ readonly isEmpty: false; /** * Returns a non-empty `Stream` containing all entries of this collection as tuples of key and value. * @example * ```ts * HashBiMultiMap.of([1, 1], [2, 2]).stream().toArray() // => [[1, 1], [2, 2]] * ``` */ stream(): Stream.NonEmpty<[K, V]>; /** * Returns a non-empty `Stream` containing all keys of this collection. * @example * ```ts * HashBiMultiMap.of([[1, 'a'], [2, 'b']]).streamKeys().toArray() // => [1, 2] * ``` */ streamKeys(): Stream.NonEmpty; /** * Returns a non-empty `Stream` containing all values of this collection. * @example * ```ts * HashBiMultiMap.of([[1, 'a'], [2, 'b']]).streamValues().toArray() // => ['a', 'b'] * ``` */ streamValues(): Stream.NonEmpty; /** * Returns this collection typed as a 'possibly empty' collection. * @example * ```ts * HashBiMultiMap.of([1, 1], [2, 2]).asNormal(); // type: HashBiMultiMap * ``` */ asNormal(): WithKeyValue['normal']; /** * Returns true since this collection is known to be non-empty * @example * ```ts * HashBiMultiMap.of([1, 1], [2, 2]).nonEmpty() // => true * ``` */ nonEmpty(): this is WithKeyValue['nonEmpty']; /** * Returns the collection with the entries from the given `StreamSource` `entries` added. * @param entries - a `StreamSource` containing tuples with a key and value * @example * ```ts * HashBiMultiMap.of([1, 1]).addEntries([[2, 2], [1, 3]]).toArray() * // => [[1, 1], [1, 3], [2, 2]] * ``` */ addEntries( entries: StreamSource ): WithKeyValue['nonEmpty']; } export interface Factory< UK = unknown, UV = unknown, Tp extends BiMultiMapBase.Types = BiMultiMapBase.Types, > { /** * Returns the (singleton) empty instance of this type and context with given key and value types. * @example * ```ts * HashBiMultiMap.empty() // => HashBiMultiMap * HashBiMultiMap.empty() // => HashBiMultiMap * ``` */ empty(): WithKeyValue['normal']; /** * Returns an immutable BiMultiMap, containing the given `entries`. * @param entries - a non-empty array of key-value entries * @example * ```ts * HashBiMultiMap.of([1, 'a'], [2, 'b']) // => HashBiMultiMap.NonEmpty * ``` */ of( ...entries: ArrayNonEmpty ): WithKeyValue['nonEmpty']; /** * Returns an immutable BiMultiMap, containing the entries in the given `sources` `StreamSource` instances. * @param sources - an array of `StreamSource` instances containing key-value entries * @example * ```ts * HashBiMultiMap.from([[1, 'a'], [2, 'b']]) // => HashBiMultiMap.NonEmpty * ``` */ from( ...sources: ArrayNonEmpty> ): WithKeyValue['nonEmpty']; from( ...sources: ArrayNonEmpty> ): WithKeyValue['normal']; /** * Returns an empty `BiMultiMap` builder instance. * @example * ```ts * HashBiMultiMap.builder() // => HashBiMultiMap.Builder * ``` */ builder(): WithKeyValue['builder']; /** * Returns a `Reducer` that adds received tuples to a BiMultiMap and returns the BiMultiMap as a result. When a `source` is given, * the reducer will first create a BiMultiMap from the source, and then add tuples to it. * @param source - (optional) an initial source of tuples to add to * @example * ```ts * const someSource = BiMultiMap.of([1, 'a'], [2, 'b']); * const result = Stream.of([1, 'c'], [3, 'a']).reduce(BiMultiMap.reducer(someSource)) * result.toArray() // => [[1, 'a'], [1, 'c'], [2, 'b'], [3, 'a']] * ``` * @note uses a builder under the hood. If the given `source` is a BiMultiMap in the same context, it will directly call `.toBuilder()`. */ reducer( source?: StreamSource ): Reducer['normal']>; } export interface Context< UK, UV, Tp extends BiMultiMapBase.Types = BiMultiMapBase.Types, > extends BiMultiMapBase.Factory { readonly _fixTypes: readonly [UK, UV]; /** * A string tag defining the specific collection type * @example * ```ts * HashBiMultiMap.defaultContext().typeTag // => 'HashBiMultiMap' * ``` */ readonly typeTag: string; readonly _types: Tp; readonly keyValueMultiMapContext: WithKeyValue< Tp, UK, UV >['keyValueMultiMapContext']; readonly valueKeyMultiMapContext: WithKeyValue< Tp, UK, UV >['valueKeyMultiMapContext']; } export interface Builder< K, V, Tp extends BiMultiMapBase.Types = BiMultiMapBase.Types, > { /** * Returns the amount of entries in the builder. * @example * ```ts * HashBiMultiMap.of([[1, 'a'], [2, 'b']]).toBuilder().size * // => 2 * ``` */ readonly size: number; /** * Returns true if there are no entries in the builder. * @example * ```ts * HashBiMultiMap.of([[1, 'a'], [2, 'b']]).toBuilder().isEmpty * // => false * ``` */ readonly isEmpty: boolean; /** * Returns true if the given `key` is present in the builder. * @param key - the key to look for * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.hasKey(2) // => true * m.hasKey(3) // => false * ``` */ hasKey(key: RelatedTo): boolean; /** * Returns true if the given `value` is present in the builder. * @param value - the value to look for * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.hasValue('a') // => true * m.hasValue('z') // => false * ``` */ hasValue(value: RelatedTo): boolean; /** * Returns true if the given `key` `value` entry is present in the builder. * @param key - the key to look for * @param value - the value to look for * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.hasEntry(1, 'a') // => true * m.hasEntry(1, 'z') // => false * ``` */ hasEntry( key: RelatedTo, value: RelatedTo ): boolean; /** * Returns a collection representing the values currently associated with given `key`. * @param key - the key for which to find the values * * @note since it is unsafe to return the internal builder object, the result collection will * be built upon each call to `getValues`. * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.getValues(1).toArray() // => ['a'] * m.getValues(3).toArray() // => [] * ``` */ getValues( key: RelatedTo ): WithKeyValue['keyMultiMapValues']; /** * Returns a collection representing the keys currently associated with given `value`. * @param value - the value for which to find the keys * * @note since it is unsafe to return the internal builder object, the result collection will * be built upon each call to `getKeys`. * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.getKeys('a').toArray() // => [1] * m.getKeys('z').toArray() // => [] * ``` */ getKeys( value: RelatedTo ): WithKeyValue['valueMultiMapValues']; /** * Sets the values associated to given `key` to the values in the given `values` StreamSource. * @param key - the key to which to associate the values * @param values - a StreamSource containing the values to associate to the key * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.setValues(1, ['b', 'c']).getValues(1).toArray() // => ['b', 'c'] * ``` */ setValues(key: K, values: StreamSource): boolean; /** * Sets the keys associated to given `value` to the keys in the given `keys` StreamSource. * @param value - the value to which to associate the keys * @param keys - a StreamSource containing the keys to associate to the value * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.setKeys('a', [3, 4]).getKeys('a').toArray() // => [3, 4] * ``` */ setKeys(value: V, keys: StreamSource): boolean; /** * Associates given `key` with given `value` in the builder. * @param key - the entry key * @param value - the entry value * @returns true if the data in the builder has changed * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.set(1, 'a') // => false * m.set(1, 'b') // => true * ``` */ add(key: K, value: V): boolean; /** * Adds given `entries` to the builder. * @param entries - a `StreamSource` containing the entries to add * @returns true if the data in the builder has changed * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.addEntries([1, 'a'], [3, 'c']]) // => true * m.addEntries([]) // => false * ``` */ addEntries(entries: StreamSource): boolean; /** * Removes the entries related to given `key` from the builder. * @param key - the key to remove * @returns true if the data in the builder has changed * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.removeKey(2) // => true * m.removeKey(3) // => false * ``` */ removeKey(key: RelatedTo): boolean; /** * Removes the entries related to the given `keys` `StreamSource` from the builder. * @param keys - the `StreamSource` containing the keys to remove. * @returns true if the data in the builder has changed * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.removeKeys([3, 4, 5]) // => false * m.removeKeys([1, 10]) // => true * ``` */ removeKeys(keys: StreamSource>): boolean; /** * Removes the entries related to given `value` from the builder. * @param value - the value to remove * @returns true if the data in the builder has changed * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.removeValue('b') // => true * m.removeValue('c') // => false * ``` */ removeValue(value: RelatedTo): boolean; /** * Removes the entries related to the given `values` `StreamSource` from the builder. * @param values - the `StreamSource` containing the values to remove. * @returns true if the data in the builder has changed * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.removeValues(['c', 'd', 'e']) // => false * m.removeValues(['a', 'e']) // => true * ``` */ removeValues(values: StreamSource>): boolean; /** * Removes the entry of given `key` and `value` from the builder. * @param key - the entry key * @param value - the entry value * @returns true if the data in the builder has changed * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.removeEntry(1, 'c') // => false * m.removeEntry(1, 'a') // => true * ``` */ removeEntry( key: RelatedTo, value: RelatedTo ): boolean; /** * Removes the entries in the given `entries` `StreamSource` from the builder. * @param entries - the `StreamSource` containing the entries to remove. * @returns true if the data in the builder has changed * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * m.removeEntries([[1, 'c'], ['2', 'a']]) // => false * m.removeEntries([[1, 'a']]) // => true * ``` */ removeEntries( entries: StreamSource<[RelatedTo, RelatedTo]> ): boolean; /** * Performs given function `f` for each entry of the builder. * @param f - the function to perform for each element, receiving:
* - `entry`: the next key-value entry
* - `index`: the index of the element
* - `halt`: a function that, if called, ensures that no new elements are passed * @throws RibuError.ModifiedBuilderWhileLoopingOverItError if the builder is modified while * looping over it * @example * ```ts * HashBiMultiMap.of([1, 'a'], [2, 'b'], [3, 'c']).toBuilder().forEach((entry, i, halt) => { * console.log([entry[1], entry[0]]); * if (i >= 1) halt(); * }) * // => logs ['a', 1] ['b', 2] * ``` * @note O(N) */ forEach( f: (entry: [K, V], index: number, halt: () => void) => void, options?: { state?: TraverseState } ): void; /** * Returns an immutable collection instance containing the entries in this builder. * @example * ```ts * const m = HashBiMultiMap.of([1, 'a'], [2, 'b']).toBuilder() * const m2: HashBiMultiMap = m.build() * ``` */ build(): WithKeyValue['normal']; } /** * Utility interface that provides higher-kinded types for this collection. */ export interface Types extends KeyValue { /** * The collection context type (higher-kinded type). */ readonly context: BiMultiMapBase.Context; /** * The 'normal' collection type (higher-kinded type). */ readonly normal: BiMultiMapBase; /** * The 'non-empty' collection type (higher-kinded type). */ readonly nonEmpty: BiMultiMapBase.NonEmpty; /** * The 'builder' collection type (higher-kinded type). */ readonly builder: BiMultiMapBase.Builder; /** * The key to value multimap context type (higher-kinded type). */ readonly keyValueMultiMapContext: MultiMap.Context; /** * The value to key multimap context type (higher-kinded type). */ readonly valueKeyMultiMapContext: MultiMap.Context; /** * The key to value multimap type (higher-kinded type). */ readonly keyValueMultiMap: MultiMap; /** * The value to key multimap type (higher-kinded type). */ readonly valueKeyMultiMap: MultiMap; /** * The non-empty key to value multimap type (higher-kinded type). */ readonly keyValueMultiMapNonEmpty: MultiMap.NonEmpty< this['_K'], this['_V'] >; /** * The non-empty value to key multimap type (higher-kinded type). */ readonly valueKeyMultiMapNonEmpty: MultiMap.NonEmpty< this['_V'], this['_K'] >; /** * The value set collection type (higher-kinded type). */ readonly keyMultiMapValues: RSet; /** * The key set collection type (higher-kinded type). */ readonly valueMultiMapValues: RSet; } }