UNPKG

data-structure-typed

Version:
1,308 lines (1,302 loc) 638 kB
"use strict"; var dataStructureTyped = (() => { var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name); var __typeError = (msg) => { throw TypeError(msg); }; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; var __await = function(promise, isYieldStar) { this[0] = promise; this[1] = isYieldStar; }; var __yieldStar = (value) => { var obj = value[__knownSymbol("asyncIterator")], isAwait = false, method, it = {}; if (obj == null) { obj = value[__knownSymbol("iterator")](); method = (k) => it[k] = (x) => obj[k](x); } else { obj = obj.call(value); method = (k) => it[k] = (v) => { if (isAwait) { isAwait = false; if (k === "throw") throw v; return v; } isAwait = true; return { done: false, value: new __await(new Promise((resolve) => { var x = obj[k](v); if (!(x instanceof Object)) __typeError("Object expected"); resolve(x); }), 1) }; }; } return it[__knownSymbol("iterator")] = () => it, method("next"), "throw" in obj ? method("throw") : it.throw = (x) => { throw x; }, "return" in obj && method("return"), it; }; // src/index.ts var src_exports = {}; __export(src_exports, { AVLTree: () => AVLTree, AVLTreeCounter: () => AVLTreeCounter, AVLTreeCounterNode: () => AVLTreeCounterNode, AVLTreeMultiMap: () => AVLTreeMultiMap, AVLTreeMultiMapNode: () => AVLTreeMultiMapNode, AVLTreeNode: () => AVLTreeNode, AbstractEdge: () => AbstractEdge, AbstractGraph: () => AbstractGraph, AbstractVertex: () => AbstractVertex, BST: () => BST, BSTNode: () => BSTNode, BinaryIndexedTree: () => BinaryIndexedTree, BinaryTree: () => BinaryTree, BinaryTreeNode: () => BinaryTreeNode, Character: () => Character, DFSOperation: () => DFSOperation, Deque: () => Deque, DirectedEdge: () => DirectedEdge, DirectedGraph: () => DirectedGraph, DirectedVertex: () => DirectedVertex, DoublyLinkedList: () => DoublyLinkedList, DoublyLinkedListNode: () => DoublyLinkedListNode, FibonacciHeap: () => FibonacciHeap, FibonacciHeapNode: () => FibonacciHeapNode, HashMap: () => HashMap, Heap: () => Heap, IterableElementBase: () => IterableElementBase, IterableEntryBase: () => IterableEntryBase, LinkedHashMap: () => LinkedHashMap, LinkedListQueue: () => LinkedListQueue, MapEdge: () => MapEdge, MapGraph: () => MapGraph, MapVertex: () => MapVertex, Matrix: () => Matrix, MaxHeap: () => MaxHeap, MaxPriorityQueue: () => MaxPriorityQueue, MinHeap: () => MinHeap, MinPriorityQueue: () => MinPriorityQueue, Navigator: () => Navigator, PriorityQueue: () => PriorityQueue, Queue: () => Queue, Range: () => Range, RedBlackTree: () => RedBlackTree, RedBlackTreeNode: () => RedBlackTreeNode, SegmentTree: () => SegmentTree, SegmentTreeNode: () => SegmentTreeNode, SinglyLinkedList: () => SinglyLinkedList, SinglyLinkedListNode: () => SinglyLinkedListNode, SkipList: () => SkipList, SkipListNode: () => SkipListNode, Stack: () => Stack, THUNK_SYMBOL: () => THUNK_SYMBOL, TreeCounter: () => TreeCounter, TreeCounterNode: () => TreeCounterNode, TreeMultiMap: () => TreeMultiMap, TreeMultiMapNode: () => TreeMultiMapNode, TreeNode: () => TreeNode, Trie: () => Trie, TrieNode: () => TrieNode, UndirectedEdge: () => UndirectedEdge, UndirectedGraph: () => UndirectedGraph, UndirectedVertex: () => UndirectedVertex, arrayRemove: () => arrayRemove, calcMinUnitsRequired: () => calcMinUnitsRequired, getMSB: () => getMSB, isComparable: () => isComparable, isThunk: () => isThunk, isWeakKey: () => isWeakKey, rangeCheck: () => rangeCheck, roundFixed: () => roundFixed, throwRangeError: () => throwRangeError, toBinaryString: () => toBinaryString, toThunk: () => toThunk, trampoline: () => trampoline, trampolineAsync: () => trampolineAsync, uuidV4: () => uuidV4 }); // src/data-structures/base/iterable-entry-base.ts var IterableEntryBase = class { /** * Time Complexity: O(n) * Space Complexity: O(1) * * The function is an implementation of the Symbol.iterator method that returns an iterable iterator. * @param {any[]} args - The `args` parameter in the code snippet represents a rest parameter. It * allows the function to accept any number of arguments as an array. In this case, the `args` * parameter is used to pass any additional arguments to the `_getIterator` method. */ *[Symbol.iterator](...args) { yield* __yieldStar(this._getIterator(...args)); } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The function returns an iterator that yields key-value pairs from the object, where the value can * be undefined. */ *entries() { for (const item of this) { yield item; } } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The function returns an iterator that yields the keys of a data structure. */ *keys() { for (const item of this) { yield item[0]; } } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The function returns an iterator that yields the values of a collection. */ *values() { for (const item of this) { yield item[1]; } } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `every` function checks if every element in a collection satisfies a given condition. * @param predicate - The `predicate` parameter is a callback function that takes three arguments: * `value`, `key`, and `index`. It should return a boolean value indicating whether the condition is * met for the current element in the iteration. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be * passed as the first argument to the `predicate` function. If `thisArg` is not provided * @returns The `every` method is returning a boolean value. It returns `true` if every element in * the collection satisfies the provided predicate function, and `false` otherwise. */ every(predicate, thisArg) { let index = 0; for (const item of this) { if (!predicate.call(thisArg, item[0], item[1], index++, this)) { return false; } } return true; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The "some" function iterates over a collection and returns true if at least one element satisfies * a given predicate. * @param predicate - The `predicate` parameter is a callback function that takes three arguments: * `value`, `key`, and `index`. It should return a boolean value indicating whether the condition is * met for the current element in the iteration. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided, * it will be passed as the first argument to the `predicate` function. If `thisArg` is * @returns a boolean value. It returns true if the predicate function returns true for any pair in * the collection, and false otherwise. */ some(predicate, thisArg) { let index = 0; for (const item of this) { if (predicate.call(thisArg, item[0], item[1], index++, this)) { return true; } } return false; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `forEach` function iterates over each key-value pair in a collection and executes a callback * function for each pair. * @param callbackfn - The callback function that will be called for each element in the collection. * It takes four parameters: the value of the current element, the key of the current element, the * index of the current element, and the collection itself. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to * specify the value of `this` within the callback function. If `thisArg` is provided, it will be * used as the `this` value when calling the callback function. If `thisArg` is not provided, ` */ forEach(callbackfn, thisArg) { let index = 0; for (const item of this) { const [key, value] = item; callbackfn.call(thisArg, key, value, index++, this); } } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `find` function iterates over the entries of a collection and returns the first value for * which the callback function returns true. * @param callbackfn - The callback function that will be called for each entry in the collection. It * takes three arguments: the value of the entry, the key of the entry, and the index of the entry in * the collection. It should return a boolean value indicating whether the current entry matches the * desired condition. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will * be passed as the `this` value to the `callbackfn` function. If `thisArg * @returns The method `find` returns the value of the first element in the iterable that satisfies * the provided callback function. If no element satisfies the callback function, `undefined` is * returned. */ find(callbackfn, thisArg) { let index = 0; for (const item of this) { const [key, value] = item; if (callbackfn.call(thisArg, key, value, index++, this)) return item; } return; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The function checks if a given key exists in a collection. * @param {K} key - The parameter "key" is of type K, which means it can be any type. It represents * the key that we want to check for existence in the data structure. * @returns a boolean value. It returns true if the key is found in the collection, and false * otherwise. */ has(key) { for (const item of this) { const [itemKey] = item; if (itemKey === key) return true; } return false; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The function checks if a given value exists in a collection. * @param {V} value - The parameter "value" is the value that we want to check if it exists in the * collection. * @returns a boolean value, either true or false. */ hasValue(value) { for (const [, elementValue] of this) { if (elementValue === value) return true; } return false; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `get` function retrieves the value associated with a given key from a collection. * @param {K} key - K (the type of the key) - This parameter represents the key that is being * searched for in the collection. * @returns The `get` method returns the value associated with the specified key if it exists in the * collection, otherwise it returns `undefined`. */ get(key) { for (const item of this) { const [itemKey, value] = item; if (itemKey === key) return value; } return; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `reduce` function iterates over key-value pairs and applies a callback function to each pair, * accumulating a single value. * @param callbackfn - The callback function that will be called for each element in the collection. * It takes four arguments: the current accumulator value, the current value of the element, the key * of the element, and the index of the element in the collection. It should return the updated * accumulator value. * @param {U} initialValue - The `initialValue` parameter is the initial value of the accumulator. It * is the value that will be used as the first argument to the `callbackfn` function when reducing * the elements of the collection. * @returns The `reduce` method is returning the final value of the accumulator after iterating over * all the elements in the collection. */ reduce(callbackfn, initialValue) { let accumulator = initialValue; let index = 0; for (const item of this) { const [key, value] = item; accumulator = callbackfn(accumulator, value, key, index++, this); } return accumulator; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The print function logs the elements of an array to the console. */ toVisual() { return [...this]; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The print function logs the elements of an array to the console. */ print() { console.log(this.toVisual()); } }; // src/data-structures/base/iterable-element-base.ts var IterableElementBase = class { /** * The protected constructor initializes the options for the IterableElementBase class, including the * toElementFn function. * @param [options] - An optional object that contains the following properties: */ constructor(options) { __publicField(this, "_toElementFn"); if (options) { const { toElementFn } = options; if (typeof toElementFn === "function") this._toElementFn = toElementFn; else if (toElementFn) throw new TypeError("toElementFn must be a function type"); } } get toElementFn() { return this._toElementFn; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The function is an implementation of the Symbol.iterator method that returns an IterableIterator. * @param {any[]} args - The `args` parameter in the code snippet represents a rest parameter. It * allows the function to accept any number of arguments as an array. In this case, the `args` * parameter is used to pass any number of arguments to the `_getIterator` method. */ *[Symbol.iterator](...args) { yield* __yieldStar(this._getIterator(...args)); } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The function returns an iterator that yields all the values in the object. */ *values() { for (const item of this) { yield item; } } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `every` function checks if every element in the array satisfies a given predicate. * @param predicate - The `predicate` parameter is a callback function that takes three arguments: * the current element being processed, its index, and the array it belongs to. It should return a * boolean value indicating whether the element satisfies a certain condition or not. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be * passed as the `this` value to the `predicate` function. If `thisArg` is * @returns The `every` method is returning a boolean value. It returns `true` if every element in * the array satisfies the provided predicate function, and `false` otherwise. */ every(predicate, thisArg) { let index = 0; for (const item of this) { if (!predicate.call(thisArg, item, index++, this)) { return false; } } return true; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The "some" function checks if at least one element in a collection satisfies a given predicate. * @param predicate - The `predicate` parameter is a callback function that takes three arguments: * `value`, `index`, and `array`. It should return a boolean value indicating whether the current * element satisfies the condition. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided, * it will be passed as the `this` value to the `predicate` function. If `thisArg * @returns a boolean value. It returns true if the predicate function returns true for any element * in the collection, and false otherwise. */ some(predicate, thisArg) { let index = 0; for (const item of this) { if (predicate.call(thisArg, item, index++, this)) { return true; } } return false; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `forEach` function iterates over each element in an array-like object and calls a callback * function for each element. * @param callbackfn - The callbackfn parameter is a function that will be called for each element in * the array. It takes three arguments: the current element being processed, the index of the current * element, and the array that forEach was called upon. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will * be passed as the `this` value to the `callbackfn` function. If `thisArg */ forEach(callbackfn, thisArg) { let index = 0; for (const item of this) { callbackfn.call(thisArg, item, index++, this); } } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `find` function iterates over the elements of an array-like object and returns the first * element that satisfies the provided callback function. * @param predicate - The predicate parameter is a function that will be called for each element in * the array. It takes three arguments: the current element being processed, the index of the current * element, and the array itself. The function should return a boolean value indicating whether the * current element matches the desired condition. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will * be passed as the `this` value to the `callbackfn` function. If `thisArg * @returns The `find` method returns the first element in the array that satisfies the provided * callback function. If no element satisfies the callback function, `undefined` is returned. */ find(predicate, thisArg) { let index = 0; for (const item of this) { if (predicate.call(thisArg, item, index++, this)) return item; } return; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The function checks if a given element exists in a collection. * @param {E} element - The parameter "element" is of type E, which means it can be any type. It * represents the element that we want to check for existence in the collection. * @returns a boolean value. It returns true if the element is found in the collection, and false * otherwise. */ has(element) { for (const ele of this) { if (ele === element) return true; } return false; } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The `reduce` function iterates over the elements of an array-like object and applies a callback * function to reduce them into a single value. * @param callbackfn - The callbackfn parameter is a function that will be called for each element in * the array. It takes four arguments: * @param {U} initialValue - The initialValue parameter is the initial value of the accumulator. It * is the value that the accumulator starts with before the reduction operation begins. * @returns The `reduce` method is returning the final value of the accumulator after iterating over * all the elements in the array and applying the callback function to each element. */ reduce(callbackfn, initialValue) { let accumulator = initialValue != null ? initialValue : 0; let index = 0; for (const item of this) { accumulator = callbackfn(accumulator, item, index++, this); } return accumulator; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The `toArray` function converts a linked list into an array. * @returns The `toArray()` method is returning an array of type `E[]`. */ toArray() { return [...this]; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The print function logs the elements of an array to the console. */ toVisual() { return [...this]; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The print function logs the elements of an array to the console. */ print() { console.log(this.toVisual()); } }; // src/utils/utils.ts var uuidV4 = function() { return "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".replace(/[x]/g, function(c) { const r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8; return v.toString(16); }); }; var arrayRemove = function(array, predicate) { let i = -1, len = array ? array.length : 0; const result = []; while (++i < len) { const value = array[i]; if (predicate(value, i, array)) { result.push(value); Array.prototype.splice.call(array, i--, 1); len--; } } return result; }; var THUNK_SYMBOL = Symbol("thunk"); var isThunk = (fnOrValue) => { return typeof fnOrValue === "function" && fnOrValue.__THUNK__ === THUNK_SYMBOL; }; var toThunk = (fn) => { const thunk = () => fn(); thunk.__THUNK__ = THUNK_SYMBOL; return thunk; }; var trampoline = (fn) => { const cont = (...args) => toThunk(() => fn(...args)); return Object.assign( (...args) => { let result = fn(...args); while (isThunk(result) && typeof result === "function") { result = result(); } return result; }, { cont } ); }; var trampolineAsync = (fn) => { const cont = (...args) => toThunk(() => fn(...args)); return Object.assign( (...args) => __async(void 0, null, function* () { let result = yield fn(...args); while (isThunk(result) && typeof result === "function") { result = yield result(); } return result; }), { cont } ); }; var getMSB = (value) => { if (value <= 0) { return 0; } return 1 << 31 - Math.clz32(value); }; var rangeCheck = (index, min, max, message = "Index out of bounds.") => { if (index < min || index > max) throw new RangeError(message); }; var throwRangeError = (message = "The value is off-limits.") => { throw new RangeError(message); }; var isWeakKey = (input) => { const inputType = typeof input; return inputType === "object" && input !== null || inputType === "function"; }; var calcMinUnitsRequired = (totalQuantity, unitSize) => Math.floor((totalQuantity + unitSize - 1) / unitSize); var roundFixed = (num, digit = 10) => { const multiplier = Math.pow(10, digit); return Math.round(num * multiplier) / multiplier; }; function isPrimitiveComparable(value) { const valueType = typeof value; if (valueType === "number") return true; return valueType === "bigint" || valueType === "string" || valueType === "boolean"; } function tryObjectToPrimitive(obj) { if (typeof obj.valueOf === "function") { const valueOfResult = obj.valueOf(); if (valueOfResult !== obj) { if (isPrimitiveComparable(valueOfResult)) return valueOfResult; if (typeof valueOfResult === "object" && valueOfResult !== null) return tryObjectToPrimitive(valueOfResult); } } if (typeof obj.toString === "function") { const stringResult = obj.toString(); if (stringResult !== "[object Object]") return stringResult; } return null; } function isComparable(value, isForceObjectComparable = false) { if (value === null || value === void 0) return false; if (isPrimitiveComparable(value)) return true; if (typeof value !== "object") return false; if (value instanceof Date) return true; if (isForceObjectComparable) return true; const comparableValue = tryObjectToPrimitive(value); if (comparableValue === null || comparableValue === void 0) return false; return isPrimitiveComparable(comparableValue); } // src/utils/number.ts function toBinaryString(num, digit = 32) { let binaryString = (num >>> 0).toString(2); binaryString = binaryString.padStart(digit, "0"); return binaryString; } // src/data-structures/hash/hash-map.ts var HashMap = class _HashMap extends IterableEntryBase { /** * The constructor function initializes a HashMap object with an optional initial collection and * options. * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type * `T`. It is an optional parameter and its default value is an empty array `[]`. * @param [options] - The `options` parameter is an optional object that can contain two properties: */ constructor(entryOrRawElements = [], options) { super(); __publicField(this, "_store", {}); __publicField(this, "_objMap", /* @__PURE__ */ new Map()); __publicField(this, "_toEntryFn"); __publicField(this, "_size", 0); __publicField(this, "_hashFn", (key) => String(key)); if (options) { const { hashFn, toEntryFn } = options; if (hashFn) this._hashFn = hashFn; if (toEntryFn) this._toEntryFn = toEntryFn; } if (entryOrRawElements) { this.setMany(entryOrRawElements); } } /** * The function returns the store object, which is a dictionary of HashMapStoreItem objects. * @returns The store property is being returned. It is a dictionary-like object with string keys and * values of type HashMapStoreItem<K, V>. */ get store() { return this._store; } /** * The function returns the object map. * @returns The `objMap` property is being returned, which is a `Map` object with keys of type * `object` and values of type `V`. */ get objMap() { return this._objMap; } /** * The function returns the value of the _toEntryFn property. * @returns The function being returned is `this._toEntryFn`. */ get toEntryFn() { return this._toEntryFn; } /** * The function returns the size of an object. * @returns The size of the object, which is a number. */ get size() { return this._size; } /** * The hasFn function is a function that takes in an item and returns a boolean * indicating whether the item is contained within the hash table. * * @return The hash function */ get hashFn() { return this._hashFn; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function checks if a given element is an array with exactly two elements. * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any * data type. * @returns a boolean value. */ isEntry(rawElement) { return Array.isArray(rawElement) && rawElement.length === 2; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function checks if the size of an object is equal to zero and returns a boolean value. * @returns A boolean value indicating whether the size of the object is 0 or not. */ isEmpty() { return this._size === 0; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The clear() function resets the state of an object by clearing its internal store, object map, and * size. */ clear() { this._store = {}; this._objMap.clear(); this._size = 0; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The `set` function adds a key-value pair to a map-like data structure, incrementing the size if * the key is not already present. * @param {K} key - The key parameter is the key used to identify the value in the data structure. It * can be of any type, but if it is an object, it will be stored in a Map, otherwise it will be * stored in a regular JavaScript object. * @param {V} value - The value parameter represents the value that you want to associate with the * key in the data structure. */ set(key, value) { if (this._isObjKey(key)) { if (!this.objMap.has(key)) { this._size++; } this.objMap.set(key, value); } else { const strKey = this._getNoObjKey(key); if (this.store[strKey] === void 0) { this._size++; } this._store[strKey] = { key, value }; } return true; } /** * Time Complexity: O(k) * Space Complexity: O(k) * * The function `setMany` takes an iterable collection of objects, maps each object to a key-value * pair using a mapping function, and sets each key-value pair in the current object. * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type * `T`. * @returns The `setMany` function is returning an array of booleans. */ setMany(entryOrRawElements) { const results = []; for (const rawEle of entryOrRawElements) { let key, value; if (this.isEntry(rawEle)) { key = rawEle[0]; value = rawEle[1]; } else if (this._toEntryFn) { const item = this._toEntryFn(rawEle); key = item[0]; value = item[1]; } if (key !== void 0 && value !== void 0) results.push(this.set(key, value)); } return results; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The `get` function retrieves a value from a map based on a given key, either from an object map or * a string map. * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be * of any type, but it should be compatible with the key type used when the map was created. * @returns The method `get(key: K)` returns a value of type `V` if the key exists in the `_objMap` * or `_store`, otherwise it returns `undefined`. */ get(key) { var _a; if (this._isObjKey(key)) { return this.objMap.get(key); } else { const strKey = this._getNoObjKey(key); return (_a = this._store[strKey]) == null ? void 0 : _a.value; } } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The `has` function checks if a given key exists in the `_objMap` or `_store` based on whether it * is an object key or not. * @param {K} key - The parameter "key" is of type K, which means it can be any type. * @returns The `has` method is returning a boolean value. */ has(key) { if (this._isObjKey(key)) { return this.objMap.has(key); } else { const strKey = this._getNoObjKey(key); return strKey in this.store; } } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The `delete` function removes an element from a map-like data structure based on the provided key. * @param {K} key - The `key` parameter is the key of the element that you want to delete from the * data structure. * @returns The `delete` method returns a boolean value. It returns `true` if the key was * successfully deleted from the map, and `false` if the key was not found in the map. */ delete(key) { if (this._isObjKey(key)) { if (this.objMap.has(key)) { this._size--; } return this.objMap.delete(key); } else { const strKey = this._getNoObjKey(key); if (strKey in this.store) { delete this.store[strKey]; this._size--; return true; } return false; } } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The clone function creates a new HashMap with the same key-value pairs as * this one. The clone function is useful for creating a copy of an existing * HashMap, and then modifying that copy without affecting the original. * * @return A new hashmap with the same values as this one */ clone() { return new _HashMap(this, { hashFn: this._hashFn, toEntryFn: this._toEntryFn }); } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The `map` function in TypeScript creates a new HashMap by applying a callback function to each * key-value pair in the original HashMap. * @param callbackfn - The callback function that will be called for each key-value pair in the * HashMap. It takes four parameters: * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will * be passed as the `this` value to the `callbackfn` function. If `thisArg * @returns The `map` method is returning a new `HashMap` object with the transformed values based on * the provided callback function. */ map(callbackfn, thisArg) { const resultMap = new _HashMap(); let index = 0; for (const [key, value] of this) { resultMap.set(key, callbackfn.call(thisArg, key, value, index++, this)); } return resultMap; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The `filter` function creates a new HashMap containing key-value pairs from the original HashMap * that satisfy a given predicate function. * @param predicate - The predicate parameter is a function that takes four arguments: value, key, * index, and map. It is used to determine whether an element should be included in the filtered map * or not. The function should return a boolean value - true if the element should be included, and * false otherwise. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be * passed as the `this` value to the `predicate` function. If `thisArg` is * @returns The `filter` method is returning a new `HashMap` object that contains the key-value pairs * from the original `HashMap` that pass the provided `predicate` function. */ filter(predicate, thisArg) { const filteredMap = new _HashMap(); let index = 0; for (const [key, value] of this) { if (predicate.call(thisArg, key, value, index++, this)) { filteredMap.set(key, value); } } return filteredMap; } /** * The function returns an iterator that yields key-value pairs from both an object store and an * object map. */ *_getIterator() { for (const node of Object.values(this.store)) { yield [node.key, node.value]; } for (const node of this.objMap) { yield node; } } /** * The function checks if a given key is an object or a function. * @param {any} key - The parameter "key" can be of any type. * @returns a boolean value. */ _isObjKey(key) { const keyType = typeof key; return (keyType === "object" || keyType === "function") && key !== null; } /** * The function `_getNoObjKey` takes a key and returns a string representation of the key, handling * different types of keys. * @param {K} key - The `key` parameter is of type `K`, which represents the type of the key being * passed to the `_getNoObjKey` function. * @returns a string value. */ _getNoObjKey(key) { const keyType = typeof key; let strKey; if (keyType !== "string" && keyType !== "number" && keyType !== "symbol") { strKey = this._hashFn(key); } else { if (keyType === "number") { strKey = key; } else { strKey = key; } } return strKey; } }; var LinkedHashMap = class _LinkedHashMap extends IterableEntryBase { /** * The constructor initializes a LinkedHashMap object with an optional raw collection and options. * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements. It is * used to initialize the HashMapLinked instance with key-value pairs. Each element in the * `entryOrRawElements` is converted to a key-value pair using the `toEntryFn` function (if provided) and * then added to the HashMap * @param [options] - The `options` parameter is an optional object that can contain the following * properties: */ constructor(entryOrRawElements = [], options) { super(); __publicField(this, "_sentinel"); __publicField(this, "_hashFn", (key) => String(key)); __publicField(this, "_objHashFn", (key) => key); __publicField(this, "_noObjMap", {}); __publicField(this, "_objMap", /* @__PURE__ */ new WeakMap()); __publicField(this, "_head"); __publicField(this, "_tail"); __publicField(this, "_toEntryFn", (rawElement) => { if (this.isEntry(rawElement)) { return rawElement; } else { throw new Error( "If the provided entryOrRawElements does not adhere to the [key, value] type format, the toEntryFn in the constructor's options parameter needs to specified." ); } }); __publicField(this, "_size", 0); this._sentinel = {}; this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel; if (options) { const { hashFn, objHashFn, toEntryFn } = options; if (hashFn) this._hashFn = hashFn; if (objHashFn) this._objHashFn = objHashFn; if (toEntryFn) { this._toEntryFn = toEntryFn; } } if (entryOrRawElements) { this.setMany(entryOrRawElements); } } /** * The function returns the hash function used for generating a hash value for a given key. * @returns The hash function that takes a key of type K and returns a string. */ get hashFn() { return this._hashFn; } /** * The function returns the object hash function. * @returns The function `objHashFn` is being returned. */ get objHashFn() { return this._objHashFn; } /** * The function returns a record of HashMapLinkedNode objects with string keys. * @returns The method is returning a Record object, which is a TypeScript type that represents an * object with string keys and values that are HashMapLinkedNode objects with keys of type K and * values of type V or undefined. */ get noObjMap() { return this._noObjMap; } /** * The function returns the WeakMap object used to map objects to HashMapLinkedNode instances. * @returns The `objMap` property is being returned. */ get objMap() { return this._objMap; } /** * The function returns the head node of a HashMapLinkedNode. * @returns The method `getHead()` is returning a `HashMapLinkedNode` object with key type `K` and * a value type `V | undefined`. */ get head() { return this._head; } /** * The function returns the tail node of a HashMapLinkedNode. * @returns The `_tail` property of type `HashMapLinkedNode<K, V | undefined>` is being returned. */ get tail() { return this._tail; } /** * The function returns the value of the _toEntryFn property. * @returns The function being returned is `this._toEntryFn`. */ get toEntryFn() { return this._toEntryFn; } /** * The function returns the size of an object. * @returns The size of the object. */ get size() { return this._size; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function returns the key-value pair at the front of a data structure. * @returns The front element of the data structure, represented as a tuple with a key (K) and a * value (V). */ get first() { if (this._size === 0) return; return [this.head.key, this.head.value]; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function returns the key-value pair at the end of a data structure. * @returns The method is returning an array containing the key-value pair of the tail element in the * data structure. */ get last() { if (this._size === 0) return; return [this.tail.key, this.tail.value]; } /** * The `begin()` function in TypeScript iterates over a linked list and yields key-value pairs. */ *begin() { let node = this.head; while (node !== this._sentinel) { yield [node.key, node.value]; node = node.next; } } /** * The function `reverseBegin()` iterates over a linked list in reverse order, yielding each node's * key and value. */ *reverseBegin() { let node = this.tail; while (node !== this._sentinel) { yield [node.key, node.value]; node = node.prev; } } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The `set` function adds a new key-value pair to a data structure, either using an object key or a * string key. * @param {K} key - The `key` parameter is the key to be set in the data structure. It can be of any * type, but typically it is a string or symbol. * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the * value associated with the key being set in the data structure. * @returns the size of the data structure after the key-value pair has been set. */ set(key, value) { let node; const isNewKey = !this.has(key); if (isWeakKey(key)) { const hash = this._objHashFn(key); node = this.objMap.get(hash); if (!node && isNewKey) { node = { key: hash, value, prev: this.tail, next: this._sentinel }; this.objMap.set(hash, node); } else if (node) { node.value = value; } } else { const hash = this._hashFn(key); node = this.noObjMap[hash]; if (!node && isNewKey) { this.noObjMap[hash] = node = { key, value, prev: this.tail, next: this._sentinel }; } else if (node) { node.value = value; } } if (node && isNewKey) { if (this._size === 0) { this._head = node; this._sentinel.next = node; } else { this.tail.next = node; node.prev = this.tail; } this._tail = node; this._sentinel.prev = node; this._size++; } return true; } /** * Time Complexity: O(k) * Space Complexity: O(k) * * The function `setMany` takes an iterable collection, converts each element into a key-value pair * using a provided function, and sets each key-value pair in the current object, returning an array * of booleans indicating the success of each set operation. * @param entryOrRawElements - The entryOrRawElements parameter is an iterable collection of elements of type * R. * @returns The `setMany` function returns an array of booleans. */ setMany(entryOrRawElements) { const results = []; for (const rawEle of entryOrRawElements) { let key, value; if (this.isEntry(rawEle)) { key = rawEle[0]; value = rawEle[1]; } else if (this._toEntryFn) { const item = this._toEntryFn(rawEle); key = item[0]; value = item[1]; } if (key !== void 0 && value !== void 0) results.push(this.set(key, value)); } return results; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function checks if a given key exists in a map, using different logic depending on whether the * key is a weak key or not. * @param {K} key - The `key` parameter is the key that is being checked for existence in the map. * @returns The method `has` is returning a boolean value. */ has(key) { if (isWeakKey(key)) { const hash = this._objHashFn(key); return this.objMap.has(hash); } else { const hash = this._hashFn(key); return hash in this.noObjMap; } } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The function `get` retrieves the value associated with a given key from a map, either by using the * key directly or by using an index stored in the key object. * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be * of any type, but typically it is a string or symbol. * @returns The value associated with the given key is being returned. If the key is an object key, * the value is retrieved from the `_nodes` array using the index stored in the `OBJ_KEY_INDEX` * property of the key. If the key is a string key, the value is retrieved from the `_noObjMap` object * using the key itself. If the key is not found, `undefined` is */ get(key) { if (isWeakKey(key)) { const hash = this._objHashFn(key); const node = this.objMap.get(hash); return node ? node.value : void 0; } else { const hash = this._hashFn(key); const node = this.noObjMap[hash]; return node ? node.value : void 0; } } /** * Time Complexity: O(n) * Space Complexity: O(1) * * The function `at` retrieves the key-value pair at a specified index in a linked list. * @param {number} index - The index parameter is a number that represents the position of the * element we want to retrieve from the data structure. * @returns The method `at(index: number)` is returning an array containing the key-value pair at * the specifi