UNPKG

deque-typed

Version:
346 lines (345 loc) 12.8 kB
/** * 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; }