deque-typed
Version:
346 lines (345 loc) • 12.8 kB
TypeScript
/**
* data-structure-typed
*
* @author Pablo Zeng
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type { EntryCallback, HashMapLinkedNode, HashMapOptions, HashMapStoreItem, LinkedHashMapOptions } from '../../types';
import { IterableEntryBase } from '../base';
/**
* Hash-based map. Supports object keys and custom hashing; offers O(1) average set/get/has.
* @remarks Time O(1), Space O(1)
* @template K
* @template V
* @template R
* 1. Key-Value Pair Storage: HashMap stores key-value pairs. Each key map to a value.
* 2. Fast Lookup: It's used when you need to quickly find, insert, or delete entries based on a key.
* 3. Unique Keys: Keys are unique.
* If you try to insert another entry with the same key, the new one will replace the old entry.
* 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.
* @example
* // should maintain insertion order
* const linkedHashMap = new LinkedHashMap<number, string>();
* linkedHashMap.set(1, 'A');
* linkedHashMap.set(2, 'B');
* linkedHashMap.set(3, 'C');
*
* const result = Array.from(linkedHashMap);
* console.log(result); // [
* // [1, 'A'],
* // [2, 'B'],
* // [3, 'C']
* // ]
* @example
* // fast lookup of values by key
* const hashMap = new HashMap<number, string>();
* hashMap.set(1, 'A');
* hashMap.set(2, 'B');
* hashMap.set(3, 'C');
*
* console.log(hashMap.get(1)); // 'A'
* console.log(hashMap.get(2)); // 'B'
* console.log(hashMap.get(3)); // 'C'
* console.log(hashMap.get(99)); // undefined
* @example
* // remove duplicates when adding multiple entries
* const hashMap = new HashMap<number, string>();
* hashMap.set(1, 'A');
* hashMap.set(2, 'B');
* hashMap.set(1, 'C'); // Update value for key 1
*
* console.log(hashMap.size); // 2
* console.log(hashMap.get(1)); // 'C'
* console.log(hashMap.get(2)); // 'B'
* @example
* // count occurrences of keys
* const data = [1, 2, 1, 3, 2, 1];
*
* const countMap = new HashMap<number, number>();
* for (const key of data) {
* countMap.set(key, (countMap.get(key) || 0) + 1);
* }
*
* console.log(countMap.get(1)); // 3
* console.log(countMap.get(2)); // 2
* console.log(countMap.get(3)); // 1
*/
export declare class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
/**
* Create a HashMap and optionally bulk-insert entries.
* @remarks Time O(N), Space O(N)
* @param [entryOrRawElements] - Iterable of entries or raw elements to insert.
* @param [options] - Options: hash function and optional record-to-entry converter.
* @returns New HashMap instance.
*/
constructor(entryOrRawElements?: Iterable<R | [K, V]>, options?: HashMapOptions<K, V, R>);
protected _store: {
[key: string]: HashMapStoreItem<K, V>;
};
/**
* Get the internal store for non-object keys.
* @remarks Time O(1), Space O(1)
* @returns Internal record of string→{key,value}.
*/
get store(): {
[p: string]: HashMapStoreItem<K, V>;
};
protected _objMap: Map<object, V>;
/**
* Get the internal Map used for object/function keys.
* @remarks Time O(1), Space O(1)
* @returns Map of object→value.
*/
get objMap(): Map<object, V>;
protected _toEntryFn?: (rawElement: R) => [K, V];
/**
* Get the raw→entry converter function if present.
* @remarks Time O(1), Space O(1)
* @returns Converter function or undefined.
*/
get toEntryFn(): ((rawElement: R) => [K, V]) | undefined;
protected _size: number;
/**
* Get the number of distinct keys stored.
* @remarks Time O(1), Space O(1)
* @returns Current size.
*/
get size(): number;
protected _hashFn: (key: K) => string;
/**
* Get the current hash function for non-object keys.
* @remarks Time O(1), Space O(1)
* @returns Hash function.
*/
get hashFn(): (key: K) => string;
/**
* Check whether the map is empty.
* @remarks Time O(1), Space O(1)
* @returns True if size is 0.
*/
isEmpty(): boolean;
/**
* Remove all entries and reset counters.
* @remarks Time O(N), Space O(1)
* @returns void
*/
clear(): void;
/**
* Type guard: check if a raw value is a [key, value] entry.
* @remarks Time O(1), Space O(1)
* @returns True if the value is a 2-tuple.
*/
isEntry(rawElement: any): rawElement is [K, V];
/**
* Insert or replace a single entry.
* @remarks Time O(1), Space O(1)
* @param key - Key.
* @param value - Value.
* @returns True when the operation succeeds.
*/
set(key: K, value: V): boolean;
/**
* Insert many entries from an iterable.
* @remarks Time O(N), Space O(N)
* @param entryOrRawElements - Iterable of entries or raw elements to insert.
* @returns Array of per-entry results.
*/
setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[];
/**
* Get the value for a key.
* @remarks Time O(1), Space O(1)
* @param key - Key to look up.
* @returns Value or undefined.
*/
get(key: K): V | undefined;
/**
* Check if a key exists.
* @remarks Time O(1), Space O(1)
* @param key - Key to test.
* @returns True if present.
*/
has(key: K): boolean;
/**
* Delete an entry by key.
* @remarks Time O(1), Space O(1)
* @param key - Key to delete.
* @returns True if the key was found and removed.
*/
delete(key: K): boolean;
/**
* Replace the hash function and rehash the non-object store.
* @remarks Time O(N), Space O(N)
* @param fn - New hash function for non-object keys.
* @returns This map instance.
*/
setHashFn(fn: (key: K) => string): this;
/**
* Deep clone this map, preserving hashing behavior.
* @remarks Time O(N), Space O(N)
* @returns A new map with the same content.
*/
clone(): this;
/**
* Map values to a new map with the same keys.
* @remarks Time O(N), Space O(N)
* @template VM
* @param callbackfn - Mapping function (key, value, index, map) → newValue.
* @param [thisArg] - Value for `this` inside the callback.
* @returns A new map with transformed values.
*/
map<VM>(callbackfn: EntryCallback<K, V, VM>, thisArg?: any): any;
/**
* Filter entries into a new map.
* @remarks Time O(N), Space O(N)
* @param predicate - Predicate (key, value, index, map) → boolean.
* @param [thisArg] - Value for `this` inside the predicate.
* @returns A new map containing entries that satisfied the predicate.
*/
filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): any;
/**
* (Protected) Create a like-kind instance and seed it from an iterable.
* @remarks Time O(N), Space O(N)
* @template TK
* @template TV
* @template TR
* @param [entries] - Iterable used to seed the new map.
* @param [options] - Options forwarded to the constructor.
* @returns A like-kind map instance.
*/
protected _createLike<TK = K, TV = V, TR = [TK, TV]>(entries?: Iterable<[TK, TV] | TR>, options?: any): any;
protected _rehashNoObj(): void;
protected _getIterator(): IterableIterator<[K, V]>;
protected _isObjKey(key: any): key is object | ((...args: any[]) => any);
protected _getNoObjKey(key: K): string;
}
/**
* Hash-based map that preserves insertion order via a doubly-linked list.
* @remarks Time O(1), Space O(1)
* @template K
* @template V
* @template R
* @example examples will be generated by unit test
*/
export declare class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
protected readonly _sentinel: HashMapLinkedNode<K, V | undefined>;
/**
* Create a LinkedHashMap and optionally bulk-insert entries.
* @remarks Time O(N), Space O(N)
* @param [entryOrRawElements] - Iterable of entries or raw elements to insert.
* @param [options] - Options: hash functions and optional record-to-entry converter.
* @returns New LinkedHashMap instance.
*/
constructor(entryOrRawElements?: Iterable<R | [K, V]>, options?: LinkedHashMapOptions<K, V, R>);
protected _hashFn: (key: K) => string;
get hashFn(): (key: K) => string;
protected _objHashFn: (key: K) => object;
/**
* Get the hash function for object/weak keys.
* @remarks Time O(1), Space O(1)
* @returns Object-hash function.
*/
get objHashFn(): (key: K) => object;
protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>>;
/**
* Get the internal record for non-object keys.
* @remarks Time O(1), Space O(1)
* @returns Record of hash→node.
*/
get noObjMap(): Record<string, HashMapLinkedNode<K, V | undefined>>;
protected _objMap: WeakMap<object, HashMapLinkedNode<K, V | undefined>>;
get objMap(): WeakMap<object, HashMapLinkedNode<K, V | undefined>>;
protected _head: HashMapLinkedNode<K, V | undefined>;
/**
* Get the head node (first entry) sentinel link.
* @remarks Time O(1), Space O(1)
* @returns Head node or sentinel.
*/
get head(): HashMapLinkedNode<K, V | undefined>;
protected _tail: HashMapLinkedNode<K, V | undefined>;
/**
* Get the tail node (last entry) sentinel link.
* @remarks Time O(1), Space O(1)
* @returns Tail node or sentinel.
*/
get tail(): HashMapLinkedNode<K, V | undefined>;
protected _toEntryFn?: (rawElement: R) => [K, V];
get toEntryFn(): ((rawElement: R) => [K, V]) | undefined;
protected _size: number;
get size(): number;
/**
* Get the first [key, value] pair.
* @remarks Time O(1), Space O(1)
* @returns First entry or undefined when empty.
*/
get first(): [K, V] | undefined;
/**
* Get the last [key, value] pair.
* @remarks Time O(1), Space O(1)
* @returns Last entry or undefined when empty.
*/
get last(): [K, V] | undefined;
/**
* Iterate from head → tail.
* @remarks Time O(N), Space O(1)
* @returns Iterator of [key, value].
*/
begin(): Generator<(K | V | undefined)[], void, unknown>;
/**
* Iterate from tail → head.
* @remarks Time O(N), Space O(1)
* @returns Iterator of [key, value].
*/
reverseBegin(): Generator<(K | V | undefined)[], void, unknown>;
/**
* Insert or replace a single entry; preserves insertion order.
* @remarks Time O(1), Space O(1)
* @param key - Key.
* @param [value] - Value.
* @returns True when the operation succeeds.
*/
set(key: K, value?: V): boolean;
setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[];
has(key: K): boolean;
get(key: K): V | undefined;
/**
* Get the value at a given index in insertion order.
* @remarks Time O(N), Space O(1)
* @param index - Zero-based index.
* @returns Value at the index.
*/
at(index: number): V | undefined;
delete(key: K): boolean;
/**
* Delete the first entry that matches a predicate.
* @remarks Time O(N), Space O(1)
* @param predicate - Function (key, value, index, map) → boolean to decide deletion.
* @returns True if an entry was removed.
*/
deleteWhere(predicate: (key: K, value: V | undefined, index: number, map: this) => boolean): boolean;
/**
* Delete the entry at a given index.
* @remarks Time O(N), Space O(1)
* @param index - Zero-based index.
* @returns True if removed.
*/
deleteAt(index: number): boolean;
isEmpty(): boolean;
isEntry(rawElement: any): rawElement is [K, V];
clear(): void;
clone(): any;
filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): any;
/**
* Map each entry to a new [key, value] pair and preserve order.
* @remarks Time O(N), Space O(N)
* @template MK
* @template MV
* @param callback - Mapping function (key, value, index, map) → [newKey, newValue].
* @param [thisArg] - Value for `this` inside the callback.
* @returns A new map of the same class with transformed entries.
*/
map<MK, MV>(callback: EntryCallback<K, V, [MK, MV]>, thisArg?: any): any;
protected _getIterator(): IterableIterator<[K, V]>;
protected _deleteNode(node: HashMapLinkedNode<K, V | undefined>): boolean;
protected _createLike<TK = K, TV = V, TR = [TK, TV]>(entries?: Iterable<[TK, TV] | TR>, options?: any): any;
}