data-structure-typed
Version:
Standard data structure
1,308 lines (1,302 loc) • 638 kB
JavaScript
"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