UNPKG

data-structure-typed

Version:
1 lines 951 kB
{"version":3,"sources":["../../src/index.ts","../../src/data-structures/base/iterable-entry-base.ts","../../src/data-structures/base/iterable-element-base.ts","../../src/utils/utils.ts","../../src/utils/number.ts","../../src/data-structures/hash/hash-map.ts","../../src/data-structures/base/linear-base.ts","../../src/data-structures/linked-list/singly-linked-list.ts","../../src/data-structures/linked-list/doubly-linked-list.ts","../../src/data-structures/linked-list/skip-linked-list.ts","../../src/data-structures/stack/stack.ts","../../src/data-structures/queue/queue.ts","../../src/data-structures/queue/deque.ts","../../src/data-structures/heap/heap.ts","../../src/data-structures/heap/max-heap.ts","../../src/data-structures/heap/min-heap.ts","../../src/data-structures/graph/abstract-graph.ts","../../src/data-structures/graph/directed-graph.ts","../../src/data-structures/graph/undirected-graph.ts","../../src/data-structures/graph/map-graph.ts","../../src/common/index.ts","../../src/data-structures/binary-tree/binary-tree.ts","../../src/data-structures/binary-tree/bst.ts","../../src/data-structures/binary-tree/binary-indexed-tree.ts","../../src/data-structures/binary-tree/segment-tree.ts","../../src/data-structures/binary-tree/avl-tree.ts","../../src/data-structures/binary-tree/red-black-tree.ts","../../src/data-structures/binary-tree/avl-tree-multi-map.ts","../../src/data-structures/binary-tree/tree-multi-map.ts","../../src/data-structures/binary-tree/tree-counter.ts","../../src/data-structures/binary-tree/avl-tree-counter.ts","../../src/data-structures/priority-queue/priority-queue.ts","../../src/data-structures/priority-queue/min-priority-queue.ts","../../src/data-structures/priority-queue/max-priority-queue.ts","../../src/data-structures/matrix/matrix.ts","../../src/data-structures/matrix/navigator.ts","../../src/data-structures/trie/trie.ts","../../src/data-structures/tree/tree.ts"],"sourcesContent":["export * from './data-structures';\nexport * from './utils';\nexport * from './interfaces';\nexport * from './types';\nexport * from './common';\n","import { EntryCallback, ReduceEntryCallback } from '../../types';\n\nexport abstract class IterableEntryBase<K = any, V = any> {\n abstract get size(): number;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function is an implementation of the Symbol.iterator method that returns an iterable iterator.\n * @param {any[]} args - The `args` parameter in the code snippet represents a rest parameter. It\n * allows the function to accept any number of arguments as an array. In this case, the `args`\n * parameter is used to pass any additional arguments to the `_getIterator` method.\n */\n *[Symbol.iterator](...args: any[]): IterableIterator<[K, V]> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields key-value pairs from the object, where the value can\n * be undefined.\n */\n *entries(): IterableIterator<[K, V | undefined]> {\n for (const item of this) {\n yield item;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields the keys of a data structure.\n */\n *keys(): IterableIterator<K> {\n for (const item of this) {\n yield item[0];\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields the values of a collection.\n */\n *values(): IterableIterator<V> {\n for (const item of this) {\n yield item[1];\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `every` function checks if every element in a collection satisfies a given condition.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `key`, and `index`. It should return a boolean value indicating whether the condition is\n * met for the current element in the iteration.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the first argument to the `predicate` function. If `thisArg` is not provided\n * @returns The `every` method is returning a boolean value. It returns `true` if every element in\n * the collection satisfies the provided predicate function, and `false` otherwise.\n */\n every(predicate: EntryCallback<K, V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (!predicate.call(thisArg, item[0], item[1], index++, this)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The \"some\" function iterates over a collection and returns true if at least one element satisfies\n * a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `key`, and `index`. It should return a boolean value indicating whether the condition is\n * met for the current element in the iteration.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided,\n * it will be passed as the first argument to the `predicate` function. If `thisArg` is\n * @returns a boolean value. It returns true if the predicate function returns true for any pair in\n * the collection, and false otherwise.\n */\n some(predicate: EntryCallback<K, V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item[0], item[1], index++, this)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `forEach` function iterates over each key-value pair in a collection and executes a callback\n * function for each pair.\n * @param callbackfn - The callback function that will be called for each element in the collection.\n * It takes four parameters: the value of the current element, the key of the current element, the\n * index of the current element, and the collection itself.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. If `thisArg` is provided, it will be\n * used as the `this` value when calling the callback function. If `thisArg` is not provided, `\n */\n forEach(callbackfn: EntryCallback<K, V, void>, thisArg?: any): void {\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n callbackfn.call(thisArg, key, value, index++, this);\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `find` function iterates over the entries of a collection and returns the first value for\n * which the callback function returns true.\n * @param callbackfn - The callback function that will be called for each entry in the collection. It\n * takes three arguments: the value of the entry, the key of the entry, and the index of the entry in\n * the collection. It should return a boolean value indicating whether the current entry matches the\n * desired condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The method `find` returns the value of the first element in the iterable that satisfies\n * the provided callback function. If no element satisfies the callback function, `undefined` is\n * returned.\n */\n find(callbackfn: EntryCallback<K, V, boolean>, thisArg?: any): [K, V] | undefined {\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n if (callbackfn.call(thisArg, key, value, index++, this)) return item;\n }\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given key exists in a collection.\n * @param {K} key - The parameter \"key\" is of type K, which means it can be any type. It represents\n * the key that we want to check for existence in the data structure.\n * @returns a boolean value. It returns true if the key is found in the collection, and false\n * otherwise.\n */\n has(key: K): boolean {\n for (const item of this) {\n const [itemKey] = item;\n if (itemKey === key) return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given value exists in a collection.\n * @param {V} value - The parameter \"value\" is the value that we want to check if it exists in the\n * collection.\n * @returns a boolean value, either true or false.\n */\n hasValue(value: V): boolean {\n for (const [, elementValue] of this) {\n if (elementValue === value) return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `get` function retrieves the value associated with a given key from a collection.\n * @param {K} key - K (the type of the key) - This parameter represents the key that is being\n * searched for in the collection.\n * @returns The `get` method returns the value associated with the specified key if it exists in the\n * collection, otherwise it returns `undefined`.\n */\n get(key: K): V | undefined {\n for (const item of this) {\n const [itemKey, value] = item;\n if (itemKey === key) return value;\n }\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reduce` function iterates over key-value pairs and applies a callback function to each pair,\n * accumulating a single value.\n * @param callbackfn - The callback function that will be called for each element in the collection.\n * It takes four arguments: the current accumulator value, the current value of the element, the key\n * of the element, and the index of the element in the collection. It should return the updated\n * accumulator value.\n * @param {U} initialValue - The `initialValue` parameter is the initial value of the accumulator. It\n * is the value that will be used as the first argument to the `callbackfn` function when reducing\n * the elements of the collection.\n * @returns The `reduce` method is returning the final value of the accumulator after iterating over\n * all the elements in the collection.\n */\n reduce<U>(callbackfn: ReduceEntryCallback<K, V, U>, initialValue: U): U {\n let accumulator = initialValue;\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n accumulator = callbackfn(accumulator, value, key, index++, this);\n }\n return accumulator;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n toVisual(): [K, V][] | string {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n print(): void {\n console.log(this.toVisual());\n }\n\n abstract isEmpty(): boolean;\n\n abstract clear(): void;\n\n abstract clone(): any;\n\n abstract map(...args: any[]): any;\n\n abstract filter(...args: any[]): any;\n\n protected abstract _getIterator(...args: any[]): IterableIterator<[K, V]>;\n}\n","import { ElementCallback, IterableElementBaseOptions, ReduceElementCallback } from '../../types';\n\nexport abstract class IterableElementBase<E, R> {\n /**\n * The protected constructor initializes the options for the IterableElementBase class, including the\n * toElementFn function.\n * @param [options] - An optional object that contains the following properties:\n */\n protected constructor(options?: IterableElementBaseOptions<E, R>) {\n if (options) {\n const { toElementFn } = options;\n if (typeof toElementFn === 'function') this._toElementFn = toElementFn;\n else if (toElementFn) throw new TypeError('toElementFn must be a function type');\n }\n }\n\n protected _toElementFn?: (rawElement: R) => E;\n\n get toElementFn(): ((rawElement: R) => E) | undefined {\n return this._toElementFn;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function is an implementation of the Symbol.iterator method that returns an IterableIterator.\n * @param {any[]} args - The `args` parameter in the code snippet represents a rest parameter. It\n * allows the function to accept any number of arguments as an array. In this case, the `args`\n * parameter is used to pass any number of arguments to the `_getIterator` method.\n */\n *[Symbol.iterator](...args: any[]): IterableIterator<E> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields all the values in the object.\n */\n *values(): IterableIterator<E> {\n for (const item of this) {\n yield item;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `every` function checks if every element in the array satisfies a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being processed, its index, and the array it belongs to. It should return a\n * boolean value indicating whether the element satisfies a certain condition or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `every` method is returning a boolean value. It returns `true` if every element in\n * the array satisfies the provided predicate function, and `false` otherwise.\n */\n every(predicate: ElementCallback<E, R, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (!predicate.call(thisArg, item, index++, this)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The \"some\" function checks if at least one element in a collection satisfies a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `index`, and `array`. It should return a boolean value indicating whether the current\n * element satisfies the condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided,\n * it will be passed as the `this` value to the `predicate` function. If `thisArg\n * @returns a boolean value. It returns true if the predicate function returns true for any element\n * in the collection, and false otherwise.\n */\n some(predicate: ElementCallback<E, R, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item, index++, this)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `forEach` function iterates over each element in an array-like object and calls a callback\n * function for each element.\n * @param callbackfn - The callbackfn parameter is a function that will be called for each element in\n * the array. It takes three arguments: the current element being processed, the index of the current\n * element, and the array that forEach was called upon.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n */\n forEach(callbackfn: ElementCallback<E, R, void>, thisArg?: any): void {\n let index = 0;\n for (const item of this) {\n callbackfn.call(thisArg, item, index++, this);\n }\n }\n\n find<S extends E>(predicate: ElementCallback<E, R, S>, thisArg?: any): S | undefined;\n find(predicate: ElementCallback<E, R, unknown>, thisArg?: any): E | undefined;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `find` function iterates over the elements of an array-like object and returns the first\n * element that satisfies the provided callback function.\n * @param predicate - The predicate parameter is a function that will be called for each element in\n * the array. It takes three arguments: the current element being processed, the index of the current\n * element, and the array itself. The function should return a boolean value indicating whether the\n * current element matches the desired condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The `find` method returns the first element in the array that satisfies the provided\n * callback function. If no element satisfies the callback function, `undefined` is returned.\n */\n find(predicate: ElementCallback<E, R, boolean>, thisArg?: any): E | undefined {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item, index++, this)) return item;\n }\n\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given element exists in a collection.\n * @param {E} element - The parameter \"element\" is of type E, which means it can be any type. It\n * represents the element that we want to check for existence in the collection.\n * @returns a boolean value. It returns true if the element is found in the collection, and false\n * otherwise.\n */\n has(element: E): boolean {\n for (const ele of this) {\n if (ele === element) return true;\n }\n return false;\n }\n\n reduce(callbackfn: ReduceElementCallback<E, R>): E;\n reduce(callbackfn: ReduceElementCallback<E, R>, initialValue: E): E;\n reduce<U>(callbackfn: ReduceElementCallback<E, R, U>, initialValue: U): U;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reduce` function iterates over the elements of an array-like object and applies a callback\n * function to reduce them into a single value.\n * @param callbackfn - The callbackfn parameter is a function that will be called for each element in\n * the array. It takes four arguments:\n * @param {U} initialValue - The initialValue parameter is the initial value of the accumulator. It\n * is the value that the accumulator starts with before the reduction operation begins.\n * @returns The `reduce` method is returning the final value of the accumulator after iterating over\n * all the elements in the array and applying the callback function to each element.\n */\n reduce<U>(callbackfn: ReduceElementCallback<E, R, U>, initialValue?: U): U {\n let accumulator = initialValue ?? (0 as U);\n let index = 0;\n for (const item of this) {\n accumulator = callbackfn(accumulator, item, index++, this);\n }\n return accumulator;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toArray` function converts a linked list into an array.\n * @returns The `toArray()` method is returning an array of type `E[]`.\n */\n toArray(): E[] {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n toVisual(): E[] {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n print(): void {\n console.log(this.toVisual());\n }\n\n abstract isEmpty(): boolean;\n\n abstract clear(): void;\n\n abstract clone(): IterableElementBase<E, R>;\n\n abstract map(...args: any[]): any;\n\n abstract filter(...args: any[]): any;\n\n protected abstract _getIterator(...args: any[]): IterableIterator<E>;\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { Comparable, ComparablePrimitive, Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';\n\n/**\n * The function generates a random UUID (Universally Unique Identifier) in TypeScript.\n * @returns A randomly generated UUID (Universally Unique Identifier) in the format\n * 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' where each 'x' is replaced with a random hexadecimal\n * character.\n */\nexport const uuidV4 = function () {\n return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n\n/**\n * The `arrayRemove` function removes elements from an array based on a specified predicate function\n * and returns the removed elements.\n * @param {T[]} array - An array of elements that you want to filter based on the provided predicate\n * function.\n * @param predicate - The `predicate` parameter is a function that takes three arguments:\n * @returns The `arrayRemove` function returns an array containing the elements that satisfy the given\n * `predicate` function.\n */\nexport const arrayRemove = function <T>(array: T[], predicate: (item: T, index: number, array: T[]) => boolean): T[] {\n let i = -1,\n len = array ? array.length : 0;\n const result = [];\n\n while (++i < len) {\n const value = array[i];\n if (predicate(value, i, array)) {\n result.push(value);\n Array.prototype.splice.call(array, i--, 1);\n len--;\n }\n }\n\n return result;\n};\n\nexport const THUNK_SYMBOL = Symbol('thunk');\n\n/**\n * The function `isThunk` checks if a given value is a function with a specific symbol property.\n * @param {any} fnOrValue - The `fnOrValue` parameter in the `isThunk` function can be either a\n * function or a value that you want to check if it is a thunk. Thunks are functions that are wrapped\n * around a value or computation for lazy evaluation. The function checks if the `fnOrValue` is\n * @returns The function `isThunk` is checking if the input `fnOrValue` is a function and if it has a\n * property `__THUNK__` equal to `THUNK_SYMBOL`. The return value will be `true` if both conditions are\n * met, otherwise it will be `false`.\n */\nexport const isThunk = (fnOrValue: any) => {\n return typeof fnOrValue === 'function' && fnOrValue.__THUNK__ === THUNK_SYMBOL;\n};\n\n/**\n * The `toThunk` function in TypeScript converts a function into a thunk by wrapping it in a closure.\n * @param {ToThunkFn} fn - `fn` is a function that will be converted into a thunk.\n * @returns A thunk function is being returned. Thunk functions are functions that delay the evaluation\n * of an expression or operation until it is explicitly called or invoked. In this case, the `toThunk`\n * function takes a function `fn` as an argument and returns a thunk function that, when called, will\n * execute the `fn` function provided as an argument.\n */\nexport const toThunk = (fn: ToThunkFn): Thunk => {\n const thunk = () => fn();\n thunk.__THUNK__ = THUNK_SYMBOL;\n return thunk;\n};\n\n/**\n * The `trampoline` function in TypeScript enables tail call optimization by using thunks to avoid\n * stack overflow.\n * @param {TrlFn} fn - The `fn` parameter in the `trampoline` function is a function that takes any\n * number of arguments and returns a value.\n * @returns The `trampoline` function returns an object with two properties:\n * 1. A function that executes the provided function `fn` and continues to execute any thunks returned\n * by `fn` until a non-thunk value is returned.\n * 2. A `cont` property that is a function which creates a thunk for the provided function `fn`.\n */\nexport const trampoline = (fn: TrlFn) => {\n const cont = (...args: [...Parameters<TrlFn>]): ReturnType<TrlFn> => toThunk(() => fn(...args));\n\n return Object.assign(\n (...args: [...Parameters<TrlFn>]) => {\n let result = fn(...args);\n\n while (isThunk(result) && typeof result === 'function') {\n result = result();\n }\n\n return result;\n },\n { cont }\n );\n};\n\n/**\n * The `trampolineAsync` function in TypeScript allows for asynchronous trampolining of a given\n * function.\n * @param {TrlAsyncFn} fn - The `fn` parameter in the `trampolineAsync` function is expected to be a\n * function that returns a Promise. This function will be called recursively until a non-thunk value is\n * returned.\n * @returns The `trampolineAsync` function returns an object with two properties:\n * 1. An async function that executes the provided `TrlAsyncFn` function and continues to execute any\n * thunks returned by the function until a non-thunk value is returned.\n * 2. A `cont` property that is a function which wraps the provided `TrlAsyncFn` function in a thunk\n * and returns it.\n */\nexport const trampolineAsync = (fn: TrlAsyncFn) => {\n const cont = (...args: [...Parameters<TrlAsyncFn>]): ReturnType<TrlAsyncFn> => toThunk(() => fn(...args));\n\n return Object.assign(\n async (...args: [...Parameters<TrlAsyncFn>]) => {\n let result = await fn(...args);\n\n while (isThunk(result) && typeof result === 'function') {\n result = await result();\n }\n\n return result;\n },\n { cont }\n );\n};\n\n/**\n * The function `getMSB` returns the most significant bit of a given number.\n * @param {number} value - The `value` parameter is a number for which we want to find the position of\n * the Most Significant Bit (MSB). The function `getMSB` takes this number as input and calculates the\n * position of the MSB in its binary representation.\n * @returns The function `getMSB` returns the most significant bit (MSB) of the input `value`. If the\n * input value is less than or equal to 0, it returns 0. Otherwise, it calculates the position of the\n * MSB using the `Math.clz32` function and bitwise left shifts 1 to that position.\n */\nexport const getMSB = (value: number): number => {\n if (value <= 0) {\n return 0;\n }\n return 1 << (31 - Math.clz32(value));\n};\n\n/**\n * The `rangeCheck` function in TypeScript is used to validate if an index is within a specified range\n * and throws a `RangeError` with a custom message if it is out of bounds.\n * @param {number} index - The `index` parameter represents the value that you want to check if it\n * falls within a specified range.\n * @param {number} min - The `min` parameter represents the minimum value that the `index` should be\n * compared against in the `rangeCheck` function.\n * @param {number} max - The `max` parameter in the `rangeCheck` function represents the maximum value\n * that the `index` parameter is allowed to have. If the `index` is greater than this `max` value, a\n * `RangeError` will be thrown.\n * @param [message=Index out of bounds.] - The `message` parameter is a string that represents the\n * error message to be thrown if the index is out of bounds. By default, if no message is provided when\n * calling the `rangeCheck` function, the message \"Index out of bounds.\" will be used.\n */\nexport const rangeCheck = (index: number, min: number, max: number, message = 'Index out of bounds.'): void => {\n if (index < min || index > max) throw new RangeError(message);\n};\n\n/**\n * The function `throwRangeError` throws a RangeError with a custom message if called.\n * @param [message=The value is off-limits.] - The `message` parameter is a string that represents the\n * error message to be displayed when a `RangeError` is thrown. If no message is provided, the default\n * message is 'The value is off-limits.'.\n */\nexport const throwRangeError = (message = 'The value is off-limits.'): void => {\n throw new RangeError(message);\n};\n\n/**\n * The function `isWeakKey` checks if the input is an object or a function in TypeScript.\n * @param {unknown} input - The `input` parameter in the `isWeakKey` function is of type `unknown`,\n * which means it can be any type. The function checks if the `input` is an object (excluding `null`)\n * or a function, and returns a boolean indicating whether the `input` is a weak\n * @returns The function `isWeakKey` returns a boolean value indicating whether the input is an object\n * or a function.\n */\nexport const isWeakKey = (input: unknown): input is object => {\n const inputType = typeof input;\n return (inputType === 'object' && input !== null) || inputType === 'function';\n};\n\n/**\n * The function `calcMinUnitsRequired` calculates the minimum number of units required to accommodate a\n * given total quantity based on a specified unit size.\n * @param {number} totalQuantity - The `totalQuantity` parameter represents the total quantity of items\n * that need to be processed or handled.\n * @param {number} unitSize - The `unitSize` parameter represents the size of each unit or package. It\n * is used in the `calcMinUnitsRequired` function to calculate the minimum number of units required to\n * accommodate a total quantity of items.\n */\nexport const calcMinUnitsRequired = (totalQuantity: number, unitSize: number) =>\n Math.floor((totalQuantity + unitSize - 1) / unitSize);\n\n/**\n * The `roundFixed` function in TypeScript rounds a number to a specified number of decimal places.\n * @param {number} num - The `num` parameter is a number that you want to round to a certain number of\n * decimal places.\n * @param {number} [digit=10] - The `digit` parameter in the `roundFixed` function specifies the number\n * of decimal places to round the number to. By default, it is set to 10 if not provided explicitly.\n * @returns The function `roundFixed` returns a number that is rounded to the specified number of\n * decimal places (default is 10 decimal places).\n */\nexport const roundFixed = (num: number, digit: number = 10) => {\n const multiplier = Math.pow(10, digit);\n return Math.round(num * multiplier) / multiplier;\n};\n\n/**\n * The function `isPrimitiveComparable` checks if a value is a primitive type that can be compared.\n * @param {unknown} value - The `value` parameter in the `isPrimitiveComparable` function is of type\n * `unknown`, which means it can be any type. The function checks if the `value` is a primitive type\n * that can be compared, such as number, bigint, string, or boolean.\n * @returns The function `isPrimitiveComparable` returns a boolean value indicating whether the input\n * `value` is a primitive value that can be compared using standard comparison operators (<, >, <=,\n * >=).\n */\nfunction isPrimitiveComparable(value: unknown): value is ComparablePrimitive {\n const valueType = typeof value;\n if (valueType === 'number') return true;\n // if (valueType === 'number') return !Number.isNaN(value);\n return valueType === 'bigint' || valueType === 'string' || valueType === 'boolean';\n}\n\n/**\n * The function `tryObjectToPrimitive` attempts to convert an object to a comparable primitive value by\n * first checking the `valueOf` method and then the `toString` method.\n * @param {object} obj - The `obj` parameter in the `tryObjectToPrimitive` function is an object that\n * you want to convert to a primitive value. The function attempts to convert the object to a primitive\n * value by first checking if the object has a `valueOf` method. If the `valueOf` method exists, it\n * @returns The function `tryObjectToPrimitive` returns a value of type `ComparablePrimitive` if a\n * primitive comparable value is found within the object, or a string value if the object has a custom\n * `toString` method that does not return `'[object Object]'`. If neither condition is met, the\n * function returns `null`.\n */\nfunction tryObjectToPrimitive(obj: object): ComparablePrimitive | null {\n if (typeof obj.valueOf === 'function') {\n const valueOfResult = obj.valueOf();\n if (valueOfResult !== obj) {\n if (isPrimitiveComparable(valueOfResult)) return valueOfResult;\n if (typeof valueOfResult === 'object' && valueOfResult !== null) return tryObjectToPrimitive(valueOfResult);\n }\n }\n if (typeof obj.toString === 'function') {\n const stringResult = obj.toString();\n if (stringResult !== '[object Object]') return stringResult;\n }\n return null;\n}\n\n/**\n * The function `isComparable` in TypeScript checks if a value is comparable, handling primitive values\n * and objects with optional force comparison.\n * @param {unknown} value - The `value` parameter in the `isComparable` function represents the value\n * that you want to check if it is comparable. It can be of any type (`unknown`), and the function will\n * determine if it is comparable based on certain conditions.\n * @param [isForceObjectComparable=false] - The `isForceObjectComparable` parameter in the\n * `isComparable` function is a boolean flag that determines whether to treat non-primitive values as\n * comparable objects. When set to `true`, it forces the function to consider non-primitive values as\n * comparable objects, regardless of their type.\n * @returns The function `isComparable` returns a boolean value indicating whether the `value` is\n * considered comparable or not.\n */\nexport function isComparable(value: unknown, isForceObjectComparable = false): value is Comparable {\n if (value === null || value === undefined) return false;\n if (isPrimitiveComparable(value)) return true;\n\n if (typeof value !== 'object') return false;\n if (value instanceof Date) return true;\n // if (value instanceof Date) return !Number.isNaN(value.getTime());\n if (isForceObjectComparable) return true;\n const comparableValue = tryObjectToPrimitive(value);\n if (comparableValue === null || comparableValue === undefined) return false;\n return isPrimitiveComparable(comparableValue);\n}\n","/**\n * The function `toBinaryString` converts a number to a binary string representation with a specified\n * number of digits.\n * @param {number} num - The `num` parameter in the `toBinaryString` function represents the number\n * that you want to convert to a binary string.\n * @param [digit=32] - The `digit` parameter in the `toBinaryString` function represents the number of\n * digits the binary string should have. By default, it is set to 32, meaning that the binary string\n * will be padded with zeros at the beginning to ensure it is 32 bits long. You can provide a\n * @returns The function `toBinaryString` takes a number as input and converts it to a binary string\n * representation with a specified number of digits (default is 32). The binary string is padded with\n * zeros at the beginning to ensure it has the specified number of digits. The function returns the\n * binary string representation of the input number.\n */\nexport function toBinaryString(num: number, digit = 32) {\n // Convert number to binary string\n let binaryString = (num >>> 0).toString(2); // Use the unsigned right shift operator to ensure you get a binary representation of a 32-bit unsigned integer\n\n // Use pad Start to ensure the string length is 32 bits\n binaryString = binaryString.padStart(digit, '0');\n\n return binaryString;\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n EntryCallback,\n HashMapLinkedNode,\n HashMapOptions,\n HashMapStoreItem,\n LinkedHashMapOptions\n} from '../../types';\nimport { IterableEntryBase } from '../base';\nimport { isWeakKey, rangeCheck } from '../../utils';\n\n/**\n * 1. Key-Value Pair Storage: HashMap stores key-value pairs. Each key map to a value.\n * 2. Fast Lookup: It's used when you need to quickly find, insert, or delete entries based on a key.\n * 3. Unique Keys: Keys are unique.\n * If you try to insert another entry with the same key, the new one will replace the old entry.\n * 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.\n * @example\n * // should maintain insertion order\n * const linkedHashMap = new LinkedHashMap<number, string>();\n * linkedHashMap.set(1, 'A');\n * linkedHashMap.set(2, 'B');\n * linkedHashMap.set(3, 'C');\n *\n * const result = Array.from(linkedHashMap);\n * console.log(result); // [\n * // [1, 'A'],\n * // [2, 'B'],\n * // [3, 'C']\n * // ]\n * @example\n * // fast lookup of values by key\n * const hashMap = new HashMap<number, string>();\n * hashMap.set(1, 'A');\n * hashMap.set(2, 'B');\n * hashMap.set(3, 'C');\n *\n * console.log(hashMap.get(1)); // 'A'\n * console.log(hashMap.get(2)); // 'B'\n * console.log(hashMap.get(3)); // 'C'\n * console.log(hashMap.get(99)); // undefined\n * @example\n * // remove duplicates when adding multiple entries\n * const hashMap = new HashMap<number, string>();\n * hashMap.set(1, 'A');\n * hashMap.set(2, 'B');\n * hashMap.set(1, 'C'); // Update value for key 1\n *\n * console.log(hashMap.size); // 2\n * console.log(hashMap.get(1)); // 'C'\n * console.log(hashMap.get(2)); // 'B'\n * @example\n * // count occurrences of keys\n * const data = [1, 2, 1, 3, 2, 1];\n *\n * const countMap = new HashMap<number, number>();\n * for (const key of data) {\n * countMap.set(key, (countMap.get(key) || 0) + 1);\n * }\n *\n * console.log(countMap.get(1)); // 3\n * console.log(countMap.get(2)); // 2\n * console.log(countMap.get(3)); // 1\n */\nexport class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {\n /**\n * The constructor function initializes a HashMap object with an optional initial collection and\n * options.\n * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type\n * `T`. It is an optional parameter and its default value is an empty array `[]`.\n * @param [options] - The `options` parameter is an optional object that can contain two properties:\n */\n constructor(entryOrRawElements: Iterable<R | [K, V]> = [], options?: HashMapOptions<K, V, R>) {\n super();\n if (options) {\n const { hashFn, toEntryFn } = options;\n if (hashFn) this._hashFn = hashFn;\n if (toEntryFn) this._toEntryFn = toEntryFn;\n }\n if (entryOrRawElements) {\n this.setMany(entryOrRawElements);\n }\n }\n\n protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};\n\n /**\n * The function returns the store object, which is a dictionary of HashMapStoreItem objects.\n * @returns The store property is being returned. It is a dictionary-like object with string keys and\n * values of type HashMapStoreItem<K, V>.\n */\n get store(): { [p: string]: HashMapStoreItem<K, V> } {\n return this._store;\n }\n\n protected _objMap: Map<object, V> = new Map();\n\n /**\n * The function returns the object map.\n * @returns The `objMap` property is being returned, which is a `Map` object with keys of type\n * `object` and values of type `V`.\n */\n get objMap(): Map<object, V> {\n return this._objMap;\n }\n\n protected _toEntryFn?: (rawElement: R) => [K, V];\n\n /**\n * The function returns the value of the _toEntryFn property.\n * @returns The function being returned is `this._toEntryFn`.\n */\n get toEntryFn() {\n return this._toEntryFn;\n }\n\n protected _size = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n protected _hashFn: (key: K) => string = (key: K) => String(key);\n\n /**\n * The hasFn function is a function that takes in an item and returns a boolean\n * indicating whether the item is contained within the hash table.\n *\n * @return The hash function\n */\n get hashFn() {\n return this._hashFn;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if a given element is an array with exactly two elements.\n * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any\n * data type.\n * @returns a boolean value.\n */\n isEntry(rawElement: any): rawElement is [K, V] {\n return Array.isArray(rawElement) && rawElement.length === 2;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if the size of an object is equal to zero and returns a boolean value.\n * @returns A boolean value indicating whether the size of the object is 0 or not.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear() function resets the state of an object by clearing its internal store, object map, and\n * size.\n */\n clear() {\n this._store = {};\n this._objMap.clear();\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `set` function adds a key-value pair to a map-like data structure, incrementing the size if\n * the key is not already present.\n * @param {K} key - The key parameter is the key used to identify the value in the data structure. It\n * can be of any type, but if it is an object, it will be stored in a Map, otherwise it will be\n * stored in a regular JavaScript object.\n * @param {V} value - The value parameter represents the value that you want to associate with the\n * key in the data structure.\n */\n set(key: K, value: V): boolean {\n if (this._isObjKey(key)) {\n if (!this.objMap.has(key)) {\n this._size++;\n }\n this.objMap.set(key, value);\n } else {\n const strKey = this._getNoObjKey(key);\n if (this.store[strKey] === undefined) {\n this._size++;\n }\n this._store[strKey] = { key, value };\n }\n return true;\n }\n\n /**\n * Time Complexity: O(k)\n * Space Complexity: O(k)\n *\n * The function `setMany` takes an iterable collection of objects, maps each object to a key-value\n * pair using a mapping function, and sets each key-value pair in the current object.\n * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type\n * `T`.\n * @returns The `setMany` function is returning an array of booleans.\n */\n setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const rawEle of entryOrRawElements) {\n let key: K | undefined, value: V | undefined;\n if (this.isEntry(rawEle)) {\n key = rawEle[0];\n value = rawEle[1];\n } else if (this._toEntryFn) {\n const item = this._toEntryFn(rawEle);\n key = item[0];\n value = item[1];\n }\n\n if (key !== undefined && value !== undefined) results.push(this.set(key, value));\n }\n return results;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `get` function retrieves a value from a map based on a given key, either from an object map or\n * a string map.\n * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be\n * of any type, but it should be compatible with the key type used when the map was created.\n * @returns The method `get(key: K)` returns a value of type `V` if the key exists in the `_objMap`\n * or `_store`, otherwise it returns `undefined`.\n */\n override get(key: K): V | undefined {\n if (this._isObjKey(key)) {\n return this.objMap.get(key);\n } else {\n const strKey = this._getNoObjKey(key);\n return this._store[strKey]?.value;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `has` function checks if a given key exists in the `_objMap` or `_store` based on whether it\n * is an object key or not.\n * @param {K} key - The parameter \"key\" is of type K, which means it can be any type.\n * @returns The `has` method is returning a boolean value.\n */\n override has(key: K): boolean {\n if (this._isObjKey(key)) {\n return this.objMap.has(key);\n } else {\n const strKey = this._getNoObjKey(key);\n return strKey in this.store;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `delete` function removes an element from a map-like data structure based on the provided key.\n * @param {K} key - The `key` parameter is the key of the element that you want to delete from the\n * data structure.\n * @returns The `delete` method returns a boolean value. It returns `true` if the key was\n * successfully deleted from the map, and `false` if the key was not found in the map.\n */\n delete(key: K): boolean {\n if (this._isObjKey(key)) {\n if (this.objMap.has(key)) {\n this._size--;\n }\n\n return this.objMap.delete(key);\n } else {\n const strKey = this._getNoObjKey(key);\n if (strKey in this.store) {\n delete this.store[strKey];\n this._size--;\n return true;\n }\n return false;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The clone function creates a new HashMap with the same key-value pairs as\n * this one. The clone function is useful for creating a copy of an existing\n * HashMap, and then modifying that copy without affecting the original.\n *\n * @return A new hashmap with the same values as this one\n */\n clone(): HashMap<K, V, R> {\n return new HashMap<K, V, R>(this, { hashFn: this._hashFn, toEntryFn: this._toEntryFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function in TypeScript creates a new HashMap by applying a callback function to each\n * key-value pair in the original HashMap.\n * @param callbackfn - The callback function that will be called for each key-value pair in the\n * HashMap. It takes four parameters:\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The `map` method is returning a new `HashMap` object with the transformed values based on\n * the provided callback function.\n */\n map<VM>(callbackfn: EntryCallback<K, V, VM>, thisArg?: any): HashMap<K, VM> {\n const resultMap = new HashMap<K, VM>();\n let index = 0;\n for (const [key, value] of this) {\n resultMap.set(key, callbackfn.call(thisArg, key, value, index++, this));\n }\n return resultMap;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new HashMap containing key-value pairs from the original HashMap\n * that satisfy a given predicate function.\n * @param predicate - The predicate parameter is a function that takes four arguments: value, key,\n * index, and map. It is used to determine whether an element should be included in the filtered map\n * or not. The function should return a boolean value - true if the element should be included, and\n * false otherwise.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `HashMap` object that contains the key-value pairs\n * from the original `HashMap` that pass the provided `predicate` function.\n */\n filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): HashMap<K, V> {\n const filteredMap = new HashMap<K, V>();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, key, value, index++, this)) {\n filteredMap.set(key, value);\n }\n }\n return filteredMap;\n }\n\n /**\n * The function returns an iterator that yields key-value pairs from both an object store and an\n * object map.\n */\n protected *_getIterator(): IterableIterator<[K, V]> {\n for (const node of Object.values(this.store)) {\n yield [node.key, node.value] as [K, V];\n }\n for (const node of this.objMap) {\n yield node as [K, V];\n }\n }\n\n /**\n * The function checks if a given key is an object or a function.\n * @param {any}