Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

heap-typed

Package Overview
Dependencies
Maintainers
1
Versions
160
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

heap-typed - npm Package Compare versions

Comparing version 1.44.1 to 1.45.0

263

dist/data-structures/hash/hash-map.d.ts

@@ -1,2 +0,1 @@

import { HashFunction } from '../../types';
/**

@@ -9,43 +8,237 @@ * data-structure-typed

*/
export declare class HashMap<K, V> {
import { HashMapLinkedNode, HashMapOptions, IterateDirection } from "../../types";
/**
* Because the implementation of HashMap relies on JavaScript's built-in objects and arrays,
* these underlying structures have already dealt with dynamic expansion and hash collisions.
* Therefore, there is no need for additional logic to handle these issues.
*/
export declare class HashMapIterator<K, V> {
readonly hashMap: HashMap<K, V>;
protected _node: HashMapLinkedNode<K, V>;
readonly iterateDirection: IterateDirection;
protected readonly _sentinel: HashMapLinkedNode<K, V>;
/**
* The constructor initializes the properties of a hash table, including the initial capacity, load factor, capacity
* multiplier, size, table array, and hash function.
* @param [initialCapacity=16] - The initial capacity is the initial size of the hash table. It determines the number of
* buckets or slots available for storing key-value pairs. The default value is 16.
* @param [loadFactor=0.75] - The load factor is a measure of how full the hash table can be before it is resized. It is
* a value between 0 and 1, where 1 means the hash table is completely full and 0 means it is completely empty. When the
* load factor is reached, the hash table will
* @param [hashFn] - The `hashFn` parameter is an optional parameter that represents the hash function used to calculate
* the index of a key in the hash table. If a custom hash function is not provided, a default hash function is used. The
* default hash function converts the key to a string, calculates the sum of the
* This is a constructor function for a linked list iterator in a HashMap data structure.
* @param node - The `node` parameter is a reference to a `HashMapLinkedNode` object. This object
* represents a node in a linked list used in a hash map data structure. It contains a key-value pair
* and references to the previous and next nodes in the linked list.
* @param sentinel - The `sentinel` parameter is a reference to a special node in a linked list. It
* is used to mark the beginning or end of the list and is typically used in data structures like
* hash maps or linked lists to simplify operations and boundary checks.
* @param hashMap - A HashMap object that stores key-value pairs.
* @param {IterateDirection} iterateDirection - The `iterateDirection` parameter is an optional
* parameter that specifies the direction in which the iterator should iterate over the elements of
* the HashMap. It can take one of the following values:
* @returns The constructor does not return anything. It is used to initialize the properties and
* methods of the object being created.
*/
constructor(initialCapacity?: number, loadFactor?: number, hashFn?: HashFunction<K>);
protected _initialCapacity: number;
get initialCapacity(): number;
protected _loadFactor: number;
get loadFactor(): number;
protected _capacityMultiplier: number;
get capacityMultiplier(): number;
constructor(node: HashMapLinkedNode<K, V>, sentinel: HashMapLinkedNode<K, V>, hashMap: HashMap<K, V>, iterateDirection?: IterateDirection);
/**
* The above function returns a Proxy object that allows access to the key and value of a node in a
* data structure.
* @returns The code is returning a Proxy object.
*/
get current(): [K, V];
/**
* The function checks if a node is accessible.
* @returns a boolean value indicating whether the `_node` is not equal to the `_sentinel`.
*/
isAccessible(): boolean;
prev(): this;
next(): this;
}
export declare class HashMap<K = any, V = any> {
protected _nodes: HashMapLinkedNode<K, V>[];
protected _orgMap: Record<string, HashMapLinkedNode<K, V>>;
protected _head: HashMapLinkedNode<K, V>;
protected _tail: HashMapLinkedNode<K, V>;
protected readonly _sentinel: HashMapLinkedNode<K, V>;
readonly OBJ_KEY_INDEX: symbol;
protected _size: number;
get size(): number;
protected _table: Array<Array<[K, V]>>;
get table(): Array<Array<[K, V]>>;
protected _hashFn: HashFunction<K>;
get hashFn(): HashFunction<K>;
set(key: K, value: V): void;
get(key: K): V | undefined;
delete(key: K): void;
entries(): IterableIterator<[K, V]>;
[Symbol.iterator](): IterableIterator<[K, V]>;
clear(): void;
/**
* The constructor initializes a HashMap object with an optional initial set of key-value pairs.
* @param hashMap - The `hashMap` parameter is an optional parameter of type `HashMapOptions<[K,
* V]>`. It is an array of key-value pairs, where each pair is represented as an array `[K, V]`. The
* `K` represents the type of the key and `V` represents the
*/
constructor(hashMap?: HashMapOptions<[K, V]>);
/**
* 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.
* @param {boolean} isObjectKey - A boolean flag indicating whether the key is an object key or not.
* @returns the size of the data structure after the key-value pair has been set.
*/
set(key: K, value?: V, isObjectKey?: boolean): number;
/**
* 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.
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that
* `key` is an object key. If `isObjectKey` is `false`, it means that `key`
* @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 `_orgMap` object
* using the key itself. If the key is not found, `undefined` is
*/
get(key: K, isObjectKey?: boolean): V | undefined;
/**
* Time Complexity: O(n), where n is the index.
* Space Complexity: O(1)
*
* The function `getAt` 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 `getAt(index: number)` is returning an array containing the key-value pair at
* the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,
* where `K` is the key and `V` is the value.
*/
getAt(index: number): [K, V];
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function `getIterator` returns a new instance of `HashMapIterator` based on the provided key
* and whether it is an object key or not.
* @param {K} key - The `key` parameter is the key used to retrieve the iterator from the HashMap. It
* can be of any type, depending on how the HashMap is implemented.
* @param {boolean} [isObjectKey] - The `isObjectKey` parameter is an optional boolean parameter that
* indicates whether the `key` parameter is an object key. If `isObjectKey` is `true`, it means that
* the `key` parameter is an object and needs to be handled differently. If `isObjectKey` is `false`
* @returns a new instance of the `HashMapIterator` class.
*/
getIterator(key: K, isObjectKey?: boolean): HashMapIterator<K, V>;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `delete` function removes a key-value pair from a map-like data structure.
* @param {K} key - The `key` parameter is the key that you want to delete from the data structure.
* It can be of any type, but typically it is a string or an object.
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that the
* `key` parameter is an object key. If `isObjectKey` is `false`, it means that the
* @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key
* was not found.
*/
delete(key: K, isObjectKey?: boolean): boolean;
/**
* Time Complexity: O(n), where n is the index.
* Space Complexity: O(1)
*
* The `deleteAt` function deletes a node at a specified index in a linked list.
* @param {number} index - The index parameter represents the position at which the node should be
* deleted in the linked list.
* @returns The size of the list after deleting the element at the specified index.
*/
deleteAt(index: number): number;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function checks if a data structure is empty by comparing its size to zero.
* @returns The method is returning a boolean value indicating whether the size of the object is 0 or
* not.
*/
isEmpty(): boolean;
protected _hash(key: K): number;
/**
* The `resizeTable` function resizes the table used in a hash map by creating a new table with a specified capacity and
* rehashing the key-value pairs from the old table into the new table.
* @param {number} newCapacity - The newCapacity parameter is the desired capacity for the resized table. It represents
* the number of buckets that the new table should have.
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `clear` function clears all the elements in a data structure and resets its properties.
*/
protected resizeTable(newCapacity: number): void;
clear(): void;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function returns a new iterator object for a HashMap.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get begin(): HashMapIterator<K, V>;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function returns a new HashMapIterator object with the _sentinel value as both the start and
* end values.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get end(): HashMapIterator<K, V>;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The reverseBegin function returns a new HashMapIterator object that iterates over the elements of
* a HashMap in reverse order.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get reverseBegin(): HashMapIterator<K, V>;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The reverseEnd function returns a new HashMapIterator object that iterates over the elements of a
* HashMap in reverse order.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get reverseEnd(): HashMapIterator<K, V>;
/**
* 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 front(): [K, V] | undefined;
/**
* 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 back(): [K, V] | undefined;
/**
* Time Complexity: O(n), where n is the number of elements in the HashMap.
* Space Complexity: O(1)
*
* The `forEach` function iterates over each element in a HashMap and executes a callback function on
* each element.
* @param callback - The callback parameter is a function that will be called for each element in the
* HashMap. It takes three arguments:
*/
forEach(callback: (element: [K, V], index: number, hashMap: HashMap<K, V>) => void): void;
/**
* Time Complexity: O(n), where n is the number of elements in the HashMap.
* Space Complexity: O(1)
*
* The above function is an iterator that yields key-value pairs from a linked list.
*/
[Symbol.iterator](): Generator<[K, V], void, unknown>;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `_deleteNode` function removes a node from a doubly linked list and updates the head and tail
* pointers if necessary.
* @param node - The `node` parameter is an instance of the `HashMapLinkedNode` class, which
* represents a node in a linked list. It contains a key-value pair and references to the previous
* and next nodes in the list.
*/
protected _deleteNode(node: HashMapLinkedNode<K, V>): void;
}

532

dist/data-structures/hash/hash-map.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HashMap = void 0;
/**

@@ -11,144 +9,458 @@ * data-structure-typed

*/
class HashMap {
Object.defineProperty(exports, "__esModule", { value: true });
exports.HashMap = exports.HashMapIterator = void 0;
const utils_1 = require("../../utils");
/**
* Because the implementation of HashMap relies on JavaScript's built-in objects and arrays,
* these underlying structures have already dealt with dynamic expansion and hash collisions.
* Therefore, there is no need for additional logic to handle these issues.
*/
class HashMapIterator {
/**
* The constructor initializes the properties of a hash table, including the initial capacity, load factor, capacity
* multiplier, size, table array, and hash function.
* @param [initialCapacity=16] - The initial capacity is the initial size of the hash table. It determines the number of
* buckets or slots available for storing key-value pairs. The default value is 16.
* @param [loadFactor=0.75] - The load factor is a measure of how full the hash table can be before it is resized. It is
* a value between 0 and 1, where 1 means the hash table is completely full and 0 means it is completely empty. When the
* load factor is reached, the hash table will
* @param [hashFn] - The `hashFn` parameter is an optional parameter that represents the hash function used to calculate
* the index of a key in the hash table. If a custom hash function is not provided, a default hash function is used. The
* default hash function converts the key to a string, calculates the sum of the
* This is a constructor function for a linked list iterator in a HashMap data structure.
* @param node - The `node` parameter is a reference to a `HashMapLinkedNode` object. This object
* represents a node in a linked list used in a hash map data structure. It contains a key-value pair
* and references to the previous and next nodes in the linked list.
* @param sentinel - The `sentinel` parameter is a reference to a special node in a linked list. It
* is used to mark the beginning or end of the list and is typically used in data structures like
* hash maps or linked lists to simplify operations and boundary checks.
* @param hashMap - A HashMap object that stores key-value pairs.
* @param {IterateDirection} iterateDirection - The `iterateDirection` parameter is an optional
* parameter that specifies the direction in which the iterator should iterate over the elements of
* the HashMap. It can take one of the following values:
* @returns The constructor does not return anything. It is used to initialize the properties and
* methods of the object being created.
*/
constructor(initialCapacity = 16, loadFactor = 0.75, hashFn) {
this._initialCapacity = initialCapacity;
this._loadFactor = loadFactor;
this._capacityMultiplier = 2;
this._size = 0;
this._table = new Array(initialCapacity);
this._hashFn =
hashFn ||
((key) => {
const strKey = String(key);
let hash = 0;
for (let i = 0; i < strKey.length; i++) {
hash += strKey.charCodeAt(i);
}
return hash % this.table.length;
});
constructor(node, sentinel, hashMap, iterateDirection = 0 /* IterateDirection.DEFAULT */) {
this._node = node;
this._sentinel = sentinel;
this.iterateDirection = iterateDirection;
if (this.iterateDirection === 0 /* IterateDirection.DEFAULT */) {
this.prev = function () {
if (this._node.prev === this._sentinel) {
(0, utils_1.throwRangeError)();
}
this._node = this._node.prev;
return this;
};
this.next = function () {
if (this._node === this._sentinel) {
(0, utils_1.throwRangeError)();
}
this._node = this._node.next;
return this;
};
}
else {
this.prev = function () {
if (this._node.next === this._sentinel) {
(0, utils_1.throwRangeError)();
}
this._node = this._node.next;
return this;
};
this.next = function () {
if (this._node === this._sentinel) {
(0, utils_1.throwRangeError)();
}
this._node = this._node.prev;
return this;
};
}
this.hashMap = hashMap;
}
get initialCapacity() {
return this._initialCapacity;
/**
* The above function returns a Proxy object that allows access to the key and value of a node in a
* data structure.
* @returns The code is returning a Proxy object.
*/
get current() {
if (this._node === this._sentinel) {
(0, utils_1.throwRangeError)();
}
return new Proxy([], {
get: (target, prop) => {
if (prop === '0')
return this._node.key;
else if (prop === '1')
return this._node.value;
target[0] = this._node.key;
target[1] = this._node.value;
return target[prop];
},
set: (_, prop, newValue) => {
if (prop !== '1') {
throw new TypeError(`prop should be string '1'`);
}
this._node.value = newValue;
return true;
}
});
}
get loadFactor() {
return this._loadFactor;
/**
* The function checks if a node is accessible.
* @returns a boolean value indicating whether the `_node` is not equal to the `_sentinel`.
*/
isAccessible() {
return this._node !== this._sentinel;
}
get capacityMultiplier() {
return this._capacityMultiplier;
prev() {
return this;
}
next() {
return this;
}
}
exports.HashMapIterator = HashMapIterator;
class HashMap {
get size() {
return this._size;
}
get table() {
return this._table;
/**
* The constructor initializes a HashMap object with an optional initial set of key-value pairs.
* @param hashMap - The `hashMap` parameter is an optional parameter of type `HashMapOptions<[K,
* V]>`. It is an array of key-value pairs, where each pair is represented as an array `[K, V]`. The
* `K` represents the type of the key and `V` represents the
*/
constructor(hashMap = []) {
this._nodes = [];
this._orgMap = {};
this.OBJ_KEY_INDEX = Symbol('OBJ_KEY_INDEX');
this._size = 0;
Object.setPrototypeOf(this._orgMap, null);
this._sentinel = {};
this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;
hashMap.forEach(el => {
this.set(el[0], el[1]);
});
}
get hashFn() {
return this._hashFn;
}
set(key, value) {
const loadFactor = this.size / this.table.length;
if (loadFactor >= this.loadFactor) {
this.resizeTable(this.table.length * this.capacityMultiplier);
/**
* 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.
* @param {boolean} isObjectKey - A boolean flag indicating whether the key is an object key or not.
* @returns the size of the data structure after the key-value pair has been set.
*/
set(key, value, isObjectKey = (0, utils_1.isObjOrFunc)(key)) {
let newTail;
if (isObjectKey) {
const index = key[this.OBJ_KEY_INDEX];
if (index !== undefined) {
this._nodes[index].value = value;
return this._size;
}
Object.defineProperty(key, this.OBJ_KEY_INDEX, {
value: this._nodes.length,
configurable: true
});
newTail = {
key: key,
value: value,
prev: this._tail,
next: this._sentinel
};
this._nodes.push(newTail);
}
const index = this._hash(key);
if (!this.table[index]) {
this.table[index] = [];
}
// Check if the key already exists in the bucket
for (let i = 0; i < this.table[index].length; i++) {
if (this.table[index][i][0] === key) {
this.table[index][i][1] = value;
return;
else {
const node = this._orgMap[key];
if (node) {
node.value = value;
return this._size;
}
this._orgMap[key] = newTail = {
key: key,
value: value,
prev: this._tail,
next: this._sentinel
};
}
this.table[index].push([key, value]);
this._size++;
if (this._size === 0) {
this._head = newTail;
this._sentinel.next = newTail;
}
else {
this._tail.next = newTail;
}
this._tail = newTail;
this._sentinel.prev = newTail;
return ++this._size;
}
get(key) {
const index = this._hash(key);
if (!this.table[index]) {
return undefined;
/**
* 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.
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that
* `key` is an object key. If `isObjectKey` is `false`, it means that `key`
* @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 `_orgMap` object
* using the key itself. If the key is not found, `undefined` is
*/
get(key, isObjectKey = (0, utils_1.isObjOrFunc)(key)) {
if (isObjectKey) {
const index = key[this.OBJ_KEY_INDEX];
return index !== undefined ? this._nodes[index].value : undefined;
}
for (const [k, v] of this.table[index]) {
if (k === key) {
return v;
const node = this._orgMap[key];
return node ? node.value : undefined;
}
/**
* Time Complexity: O(n), where n is the index.
* Space Complexity: O(1)
*
* The function `getAt` 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 `getAt(index: number)` is returning an array containing the key-value pair at
* the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,
* where `K` is the key and `V` is the value.
*/
getAt(index) {
(0, utils_1.rangeCheck)(index, 0, this._size - 1);
let node = this._head;
while (index--) {
node = node.next;
}
return [node.key, node.value];
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function `getIterator` returns a new instance of `HashMapIterator` based on the provided key
* and whether it is an object key or not.
* @param {K} key - The `key` parameter is the key used to retrieve the iterator from the HashMap. It
* can be of any type, depending on how the HashMap is implemented.
* @param {boolean} [isObjectKey] - The `isObjectKey` parameter is an optional boolean parameter that
* indicates whether the `key` parameter is an object key. If `isObjectKey` is `true`, it means that
* the `key` parameter is an object and needs to be handled differently. If `isObjectKey` is `false`
* @returns a new instance of the `HashMapIterator` class.
*/
getIterator(key, isObjectKey) {
let node;
if (isObjectKey) {
const index = key[this.OBJ_KEY_INDEX];
if (index === undefined) {
node = this._sentinel;
}
else {
node = this._nodes[index];
}
}
return undefined;
else {
node = this._orgMap[key] || this._sentinel;
}
return new HashMapIterator(node, this._sentinel, this);
}
delete(key) {
const index = this._hash(key);
if (!this.table[index]) {
return;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `delete` function removes a key-value pair from a map-like data structure.
* @param {K} key - The `key` parameter is the key that you want to delete from the data structure.
* It can be of any type, but typically it is a string or an object.
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that the
* `key` parameter is an object key. If `isObjectKey` is `false`, it means that the
* @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key
* was not found.
*/
delete(key, isObjectKey = (0, utils_1.isObjOrFunc)(key)) {
let node;
if (isObjectKey) {
const index = key[this.OBJ_KEY_INDEX];
if (index === undefined)
return false;
delete key[this.OBJ_KEY_INDEX];
node = this._nodes[index];
delete this._nodes[index];
}
for (let i = 0; i < this.table[index].length; i++) {
if (this.table[index][i][0] === key) {
this.table[index].splice(i, 1);
this._size--;
// Check if the table needs to be resized down
const loadFactor = this.size / this.table.length;
if (loadFactor < this.loadFactor / this.capacityMultiplier) {
this.resizeTable(this.table.length / this.capacityMultiplier);
}
return;
}
else {
node = this._orgMap[key];
if (node === undefined)
return false;
delete this._orgMap[key];
}
this._deleteNode(node);
return true;
}
*entries() {
for (const bucket of this.table) {
if (bucket) {
for (const [key, value] of bucket) {
yield [key, value];
}
}
/**
* Time Complexity: O(n), where n is the index.
* Space Complexity: O(1)
*
* The `deleteAt` function deletes a node at a specified index in a linked list.
* @param {number} index - The index parameter represents the position at which the node should be
* deleted in the linked list.
* @returns The size of the list after deleting the element at the specified index.
*/
deleteAt(index) {
(0, utils_1.rangeCheck)(index, 0, this._size - 1);
let node = this._head;
while (index--) {
node = node.next;
}
this._deleteNode(node);
return this._size;
}
[Symbol.iterator]() {
return this.entries();
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function checks if a data structure is empty by comparing its size to zero.
* @returns The method is returning 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 clears all the elements in a data structure and resets its properties.
*/
clear() {
// const OBJ_KEY_INDEX = this.OBJ_KEY_INDEX;
// this._nodes.forEach(el => {
// delete (<Record<symbol, number>><unknown>el.key)[OBJ_KEY_INDEX];
// });
this._nodes = [];
this._orgMap = {};
Object.setPrototypeOf(this._orgMap, null);
this._size = 0;
this._table = new Array(this.initialCapacity);
this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
}
isEmpty() {
return this.size === 0;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function returns a new iterator object for a HashMap.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get begin() {
return new HashMapIterator(this._head, this._sentinel, this);
}
_hash(key) {
return this._hashFn(key);
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function returns a new HashMapIterator object with the _sentinel value as both the start and
* end values.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get end() {
return new HashMapIterator(this._sentinel, this._sentinel, this);
}
/**
* The `resizeTable` function resizes the table used in a hash map by creating a new table with a specified capacity and
* rehashing the key-value pairs from the old table into the new table.
* @param {number} newCapacity - The newCapacity parameter is the desired capacity for the resized table. It represents
* the number of buckets that the new table should have.
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The reverseBegin function returns a new HashMapIterator object that iterates over the elements of
* a HashMap in reverse order.
* @returns A new instance of the HashMapIterator class is being returned.
*/
resizeTable(newCapacity) {
const newTable = new Array(newCapacity);
for (const bucket of this._table) {
// Note that this is this._table
if (bucket) {
for (const [key, value] of bucket) {
const newIndex = this._hash(key) % newCapacity;
if (!newTable[newIndex]) {
newTable[newIndex] = [];
}
newTable[newIndex].push([key, value]);
}
}
get reverseBegin() {
return new HashMapIterator(this._tail, this._sentinel, this, 1 /* IterateDirection.REVERSE */);
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The reverseEnd function returns a new HashMapIterator object that iterates over the elements of a
* HashMap in reverse order.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get reverseEnd() {
return new HashMapIterator(this._sentinel, this._sentinel, this, 1 /* IterateDirection.REVERSE */);
}
/**
* 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 front() {
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 back() {
if (this._size === 0)
return;
return [this._tail.key, this._tail.value];
}
/**
* Time Complexity: O(n), where n is the number of elements in the HashMap.
* Space Complexity: O(1)
*
* The `forEach` function iterates over each element in a HashMap and executes a callback function on
* each element.
* @param callback - The callback parameter is a function that will be called for each element in the
* HashMap. It takes three arguments:
*/
forEach(callback) {
let index = 0;
let node = this._head;
while (node !== this._sentinel) {
callback([node.key, node.value], index++, this);
node = node.next;
}
this._table = newTable; // Again, here is this._table
}
/**
* Time Complexity: O(n), where n is the number of elements in the HashMap.
* Space Complexity: O(1)
*
* The above function is an iterator that yields key-value pairs from a linked list.
*/
*[Symbol.iterator]() {
let node = this._head;
while (node !== this._sentinel) {
yield [node.key, node.value];
node = node.next;
}
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `_deleteNode` function removes a node from a doubly linked list and updates the head and tail
* pointers if necessary.
* @param node - The `node` parameter is an instance of the `HashMapLinkedNode` class, which
* represents a node in a linked list. It contains a key-value pair and references to the previous
* and next nodes in the list.
*/
_deleteNode(node) {
const { prev, next } = node;
prev.next = next;
next.prev = prev;
if (node === this._head) {
this._head = next;
}
if (node === this._tail) {
this._tail = prev;
}
this._size -= 1;
}
}
exports.HashMap = HashMap;

@@ -1,1 +0,15 @@

export {};
export declare const enum IterateDirection {
DEFAULT = 0,
REVERSE = 1
}
export type HashMapOptions<T> = {
sizeFunction?: number | (() => number);
fixedLength?: number;
forEach: (callback: (el: T) => void) => void;
};
export type HashMapLinkedNode<K, V> = {
key: K;
value: V;
next: HashMapLinkedNode<K, V>;
prev: HashMapLinkedNode<K, V>;
};

@@ -0,1 +1,7 @@

export * from './coordinate-map';
export * from './coordinate-set';
export * from './hash-map';
export * from './hash-table';
export * from './tree-map';
export * from './tree-set';
export type HashFunction<K> = (key: K) => number;
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./coordinate-map"), exports);
__exportStar(require("./coordinate-set"), exports);
__exportStar(require("./hash-map"), exports);
__exportStar(require("./hash-table"), exports);
__exportStar(require("./tree-map"), exports);
__exportStar(require("./tree-set"), exports);

@@ -21,1 +21,4 @@ /**

export declare const getMSB: (value: number) => number;
export declare const rangeCheck: (index: number, min: number, max: number, message?: string) => void;
export declare const throwRangeError: (message?: string) => void;
export declare const isObjOrFunc: (input: unknown) => input is Record<string, unknown> | ((...args: any[]) => any);

@@ -12,3 +12,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getMSB = exports.trampolineAsync = exports.trampoline = exports.toThunk = exports.isThunk = exports.THUNK_SYMBOL = exports.arrayRemove = exports.uuidV4 = void 0;
exports.isObjOrFunc = exports.throwRangeError = exports.rangeCheck = exports.getMSB = exports.trampolineAsync = exports.trampoline = exports.toThunk = exports.isThunk = exports.THUNK_SYMBOL = exports.arrayRemove = exports.uuidV4 = void 0;
const uuidV4 = function () {

@@ -75,1 +75,15 @@ return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function (c) {

exports.getMSB = getMSB;
const rangeCheck = (index, min, max, message = 'Index out of bounds.') => {
if (index < min || index > max)
throw new RangeError(message);
};
exports.rangeCheck = rangeCheck;
const throwRangeError = (message = 'The value is off-limits.') => {
throw new RangeError(message);
};
exports.throwRangeError = throwRangeError;
const isObjOrFunc = (input) => {
const inputType = typeof input;
return (inputType === 'object' && input !== null) || inputType === 'function';
};
exports.isObjOrFunc = isObjOrFunc;
{
"name": "heap-typed",
"version": "1.44.1",
"version": "1.45.0",
"description": "Heap. Javascript & Typescript Data Structure.",

@@ -134,4 +134,4 @@ "main": "dist/index.js",

"dependencies": {
"data-structure-typed": "^1.44.1"
"data-structure-typed": "^1.45.0"
}
}

@@ -1,3 +0,1 @@

import {HashFunction} from '../../types';
/**

@@ -10,177 +8,486 @@ * data-structure-typed

*/
export class HashMap<K, V> {
import {isObjOrFunc, rangeCheck, throwRangeError} from "../../utils";
import {HashMapLinkedNode, HashMapOptions, IterateDirection} from "../../types";
/**
* Because the implementation of HashMap relies on JavaScript's built-in objects and arrays,
* these underlying structures have already dealt with dynamic expansion and hash collisions.
* Therefore, there is no need for additional logic to handle these issues.
*/
export class HashMapIterator<K, V> {
readonly hashMap: HashMap<K, V>;
protected _node: HashMapLinkedNode<K, V>;
readonly iterateDirection: IterateDirection;
protected readonly _sentinel: HashMapLinkedNode<K, V>;
/**
* The constructor initializes the properties of a hash table, including the initial capacity, load factor, capacity
* multiplier, size, table array, and hash function.
* @param [initialCapacity=16] - The initial capacity is the initial size of the hash table. It determines the number of
* buckets or slots available for storing key-value pairs. The default value is 16.
* @param [loadFactor=0.75] - The load factor is a measure of how full the hash table can be before it is resized. It is
* a value between 0 and 1, where 1 means the hash table is completely full and 0 means it is completely empty. When the
* load factor is reached, the hash table will
* @param [hashFn] - The `hashFn` parameter is an optional parameter that represents the hash function used to calculate
* the index of a key in the hash table. If a custom hash function is not provided, a default hash function is used. The
* default hash function converts the key to a string, calculates the sum of the
* This is a constructor function for a linked list iterator in a HashMap data structure.
* @param node - The `node` parameter is a reference to a `HashMapLinkedNode` object. This object
* represents a node in a linked list used in a hash map data structure. It contains a key-value pair
* and references to the previous and next nodes in the linked list.
* @param sentinel - The `sentinel` parameter is a reference to a special node in a linked list. It
* is used to mark the beginning or end of the list and is typically used in data structures like
* hash maps or linked lists to simplify operations and boundary checks.
* @param hashMap - A HashMap object that stores key-value pairs.
* @param {IterateDirection} iterateDirection - The `iterateDirection` parameter is an optional
* parameter that specifies the direction in which the iterator should iterate over the elements of
* the HashMap. It can take one of the following values:
* @returns The constructor does not return anything. It is used to initialize the properties and
* methods of the object being created.
*/
constructor(initialCapacity = 16, loadFactor = 0.75, hashFn?: HashFunction<K>) {
this._initialCapacity = initialCapacity;
this._loadFactor = loadFactor;
this._capacityMultiplier = 2;
this._size = 0;
this._table = new Array(initialCapacity);
this._hashFn =
hashFn ||
((key: K) => {
const strKey = String(key);
let hash = 0;
for (let i = 0; i < strKey.length; i++) {
hash += strKey.charCodeAt(i);
constructor(node: HashMapLinkedNode<K, V>, sentinel: HashMapLinkedNode<K, V>,
hashMap: HashMap<K, V>, iterateDirection: IterateDirection = IterateDirection.DEFAULT) {
this._node = node;
this._sentinel = sentinel;
this.iterateDirection = iterateDirection;
if (this.iterateDirection === IterateDirection.DEFAULT) {
this.prev = function () {
if (this._node.prev === this._sentinel) {
throwRangeError();
}
return hash % this.table.length;
});
this._node = this._node.prev;
return this;
};
this.next = function () {
if (this._node === this._sentinel) {
throwRangeError();
}
this._node = this._node.next;
return this;
};
} else {
this.prev = function () {
if (this._node.next === this._sentinel) {
throwRangeError();
}
this._node = this._node.next;
return this;
};
this.next = function () {
if (this._node === this._sentinel) {
throwRangeError();
}
this._node = this._node.prev;
return this;
};
}
this.hashMap = hashMap;
}
protected _initialCapacity: number;
/**
* The above function returns a Proxy object that allows access to the key and value of a node in a
* data structure.
* @returns The code is returning a Proxy object.
*/
get current() {
if (this._node === this._sentinel) {
throwRangeError();
}
get initialCapacity(): number {
return this._initialCapacity;
return new Proxy(<[K, V]><unknown>[], {
get: (target, prop: '0' | '1') => {
if (prop === '0') return this._node.key;
else if (prop === '1') return this._node.value;
target[0] = this._node.key;
target[1] = this._node.value;
return target[prop];
},
set: (_, prop: '1', newValue: V) => {
if (prop !== '1') {
throw new TypeError(`prop should be string '1'`);
}
this._node.value = newValue;
return true;
}
});
}
protected _loadFactor: number;
get loadFactor(): number {
return this._loadFactor;
/**
* The function checks if a node is accessible.
* @returns a boolean value indicating whether the `_node` is not equal to the `_sentinel`.
*/
isAccessible() {
return this._node !== this._sentinel;
}
protected _capacityMultiplier: number;
get capacityMultiplier(): number {
return this._capacityMultiplier;
prev() {
return this;
}
protected _size: number;
next() {
return this;
}
}
get size(): number {
export class HashMap<K = any, V = any> {
protected _nodes: HashMapLinkedNode<K, V>[] = [];
protected _orgMap: Record<string, HashMapLinkedNode<K, V>> = {};
protected _head: HashMapLinkedNode<K, V>;
protected _tail: HashMapLinkedNode<K, V>;
protected readonly _sentinel: HashMapLinkedNode<K, V>;
readonly OBJ_KEY_INDEX = Symbol('OBJ_KEY_INDEX');
protected _size = 0;
get size() {
return this._size;
}
protected _table: Array<Array<[K, V]>>;
/**
* The constructor initializes a HashMap object with an optional initial set of key-value pairs.
* @param hashMap - The `hashMap` parameter is an optional parameter of type `HashMapOptions<[K,
* V]>`. It is an array of key-value pairs, where each pair is represented as an array `[K, V]`. The
* `K` represents the type of the key and `V` represents the
*/
constructor(hashMap: HashMapOptions<[K, V]> = []) {
Object.setPrototypeOf(this._orgMap, null);
this._sentinel = <HashMapLinkedNode<K, V>>{};
this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;
get table(): Array<Array<[K, V]>> {
return this._table;
hashMap.forEach(el => {
this.set(el[0], el[1]);
});
}
protected _hashFn: HashFunction<K>;
get hashFn(): HashFunction<K> {
return this._hashFn;
/**
* 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.
* @param {boolean} isObjectKey - A boolean flag indicating whether the key is an object key or not.
* @returns the size of the data structure after the key-value pair has been set.
*/
set(key: K, value?: V, isObjectKey: boolean = isObjOrFunc(key)) {
let newTail;
if (isObjectKey) {
const index = (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
if (index !== undefined) {
this._nodes[<number>index].value = <V>value;
return this._size;
}
Object.defineProperty(key, this.OBJ_KEY_INDEX, {
value: this._nodes.length,
configurable: true
});
newTail = {
key: key,
value: <V>value,
prev: this._tail,
next: this._sentinel
};
this._nodes.push(newTail);
} else {
const node = this._orgMap[<string><unknown>key];
if (node) {
node.value = <V>value;
return this._size;
}
this._orgMap[<string><unknown>key] = newTail = {
key: key,
value: <V>value,
prev: this._tail,
next: this._sentinel
};
}
if (this._size === 0) {
this._head = newTail;
this._sentinel.next = newTail;
} else {
this._tail.next = newTail;
}
this._tail = newTail;
this._sentinel.prev = newTail;
return ++this._size;
}
set(key: K, value: V): void {
const loadFactor = this.size / this.table.length;
if (loadFactor >= this.loadFactor) {
this.resizeTable(this.table.length * this.capacityMultiplier);
/**
* 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.
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that
* `key` is an object key. If `isObjectKey` is `false`, it means that `key`
* @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 `_orgMap` object
* using the key itself. If the key is not found, `undefined` is
*/
get(key: K, isObjectKey: boolean = isObjOrFunc(key)) {
if (isObjectKey) {
const index = (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
return index !== undefined ? this._nodes[index].value : undefined;
}
const node = this._orgMap[<string><unknown>key];
return node ? node.value : undefined;
}
const index = this._hash(key);
if (!this.table[index]) {
this.table[index] = [];
/**
* Time Complexity: O(n), where n is the index.
* Space Complexity: O(1)
*
* The function `getAt` 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 `getAt(index: number)` is returning an array containing the key-value pair at
* the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,
* where `K` is the key and `V` is the value.
*/
getAt(index: number) {
rangeCheck(index, 0, this._size - 1);
let node = this._head;
while (index--) {
node = node.next;
}
return <[K, V]>[node.key, node.value];
}
// Check if the key already exists in the bucket
for (let i = 0; i < this.table[index].length; i++) {
if (this.table[index][i][0] === key) {
this.table[index][i][1] = value;
return;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function `getIterator` returns a new instance of `HashMapIterator` based on the provided key
* and whether it is an object key or not.
* @param {K} key - The `key` parameter is the key used to retrieve the iterator from the HashMap. It
* can be of any type, depending on how the HashMap is implemented.
* @param {boolean} [isObjectKey] - The `isObjectKey` parameter is an optional boolean parameter that
* indicates whether the `key` parameter is an object key. If `isObjectKey` is `true`, it means that
* the `key` parameter is an object and needs to be handled differently. If `isObjectKey` is `false`
* @returns a new instance of the `HashMapIterator` class.
*/
getIterator(key: K, isObjectKey?: boolean) {
let node: HashMapLinkedNode<K, V>
if (isObjectKey) {
const index = (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
if (index === undefined) {
node = this._sentinel
} else {
node = this._nodes[index];
}
} else {
node = this._orgMap[<string><unknown>key] || this._sentinel;
}
this.table[index].push([key, value]);
this._size++;
return new HashMapIterator<K, V>(node, this._sentinel, this);
}
get(key: K): V | undefined {
const index = this._hash(key);
if (!this.table[index]) {
return undefined;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `delete` function removes a key-value pair from a map-like data structure.
* @param {K} key - The `key` parameter is the key that you want to delete from the data structure.
* It can be of any type, but typically it is a string or an object.
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that the
* `key` parameter is an object key. If `isObjectKey` is `false`, it means that the
* @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key
* was not found.
*/
delete(key: K, isObjectKey: boolean = isObjOrFunc(key)) {
let node;
if (isObjectKey) {
const index = (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
if (index === undefined) return false;
delete (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
node = this._nodes[index];
delete this._nodes[index];
} else {
node = this._orgMap[<string><unknown>key];
if (node === undefined) return false;
delete this._orgMap[<string><unknown>key];
}
this._deleteNode(node);
return true;
}
for (const [k, v] of this.table[index]) {
if (k === key) {
return v;
}
/**
* Time Complexity: O(n), where n is the index.
* Space Complexity: O(1)
*
* The `deleteAt` function deletes a node at a specified index in a linked list.
* @param {number} index - The index parameter represents the position at which the node should be
* deleted in the linked list.
* @returns The size of the list after deleting the element at the specified index.
*/
deleteAt(index: number) {
rangeCheck(index, 0, this._size - 1);
let node = this._head;
while (index--) {
node = node.next;
}
this._deleteNode(node);
return this._size;
}
return undefined;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function checks if a data structure is empty by comparing its size to zero.
* @returns The method is returning a boolean value indicating whether the size of the object is 0 or
* not.
*/
isEmpty() {
return this._size === 0;
}
delete(key: K): void {
const index = this._hash(key);
if (!this.table[index]) {
return;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `clear` function clears all the elements in a data structure and resets its properties.
*/
clear() {
// const OBJ_KEY_INDEX = this.OBJ_KEY_INDEX;
// this._nodes.forEach(el => {
// delete (<Record<symbol, number>><unknown>el.key)[OBJ_KEY_INDEX];
// });
this._nodes = [];
this._orgMap = {};
Object.setPrototypeOf(this._orgMap, null);
this._size = 0;
this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
}
for (let i = 0; i < this.table[index].length; i++) {
if (this.table[index][i][0] === key) {
this.table[index].splice(i, 1);
this._size--;
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function returns a new iterator object for a HashMap.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get begin() {
return new HashMapIterator<K, V>(this._head, this._sentinel, this);
}
// Check if the table needs to be resized down
const loadFactor = this.size / this.table.length;
if (loadFactor < this.loadFactor / this.capacityMultiplier) {
this.resizeTable(this.table.length / this.capacityMultiplier);
}
return;
}
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function returns a new HashMapIterator object with the _sentinel value as both the start and
* end values.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get end() {
return new HashMapIterator<K, V>(this._sentinel, this._sentinel, this);
}
*entries(): IterableIterator<[K, V]> {
for (const bucket of this.table) {
if (bucket) {
for (const [key, value] of bucket) {
yield [key, value];
}
}
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The reverseBegin function returns a new HashMapIterator object that iterates over the elements of
* a HashMap in reverse order.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get reverseBegin() {
return new HashMapIterator<K, V>(this._tail, this._sentinel, this, IterateDirection.REVERSE);
}
[Symbol.iterator](): IterableIterator<[K, V]> {
return this.entries();
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The reverseEnd function returns a new HashMapIterator object that iterates over the elements of a
* HashMap in reverse order.
* @returns A new instance of the HashMapIterator class is being returned.
*/
get reverseEnd() {
return new HashMapIterator<K, V>(this._sentinel, this._sentinel, this, IterateDirection.REVERSE);
}
clear(): void {
this._size = 0;
this._table = new Array(this.initialCapacity);
/**
* 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 front() {
if (this._size === 0) return;
return <[K, V]>[this._head.key, this._head.value];
}
isEmpty(): boolean {
return this.size === 0;
/**
* 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 back() {
if (this._size === 0) return;
return <[K, V]>[this._tail.key, this._tail.value];
}
protected _hash(key: K): number {
return this._hashFn(key);
/**
* Time Complexity: O(n), where n is the number of elements in the HashMap.
* Space Complexity: O(1)
*
* The `forEach` function iterates over each element in a HashMap and executes a callback function on
* each element.
* @param callback - The callback parameter is a function that will be called for each element in the
* HashMap. It takes three arguments:
*/
forEach(callback: (element: [K, V], index: number, hashMap: HashMap<K, V>) => void) {
let index = 0;
let node = this._head;
while (node !== this._sentinel) {
callback(<[K, V]>[node.key, node.value], index++, this);
node = node.next;
}
}
/**
* The `resizeTable` function resizes the table used in a hash map by creating a new table with a specified capacity and
* rehashing the key-value pairs from the old table into the new table.
* @param {number} newCapacity - The newCapacity parameter is the desired capacity for the resized table. It represents
* the number of buckets that the new table should have.
* Time Complexity: O(n), where n is the number of elements in the HashMap.
* Space Complexity: O(1)
*
* The above function is an iterator that yields key-value pairs from a linked list.
*/
protected resizeTable(newCapacity: number): void {
const newTable = new Array(newCapacity);
for (const bucket of this._table) {
// Note that this is this._table
if (bucket) {
for (const [key, value] of bucket) {
const newIndex = this._hash(key) % newCapacity;
if (!newTable[newIndex]) {
newTable[newIndex] = [];
}
newTable[newIndex].push([key, value]);
}
}
* [Symbol.iterator]() {
let node = this._head;
while (node !== this._sentinel) {
yield <[K, V]>[node.key, node.value];
node = node.next;
}
this._table = newTable; // Again, here is this._table
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `_deleteNode` function removes a node from a doubly linked list and updates the head and tail
* pointers if necessary.
* @param node - The `node` parameter is an instance of the `HashMapLinkedNode` class, which
* represents a node in a linked list. It contains a key-value pair and references to the previous
* and next nodes in the list.
*/
protected _deleteNode(node: HashMapLinkedNode<K, V>) {
const {prev, next} = node;
prev.next = next;
next.prev = prev;
if (node === this._head) {
this._head = next;
}
if (node === this._tail) {
this._tail = prev;
}
this._size -= 1;
}
}

@@ -1,1 +0,17 @@

export {};
export const enum IterateDirection {
DEFAULT = 0,
REVERSE = 1
}
export type HashMapOptions<T> = {
sizeFunction?: number | (() => number);
fixedLength?: number;
forEach: (callback: (el: T) => void) => void;
}
export type HashMapLinkedNode<K, V> = {
key: K
value: V
next: HashMapLinkedNode<K, V>
prev: HashMapLinkedNode<K, V>
}

@@ -0,1 +1,8 @@

export * from './coordinate-map';
export * from './coordinate-set';
export * from './hash-map';
export * from './hash-table';
export * from './tree-map';
export * from './tree-set';
export type HashFunction<K> = (key: K) => number;

@@ -87,1 +87,14 @@ /**

};
export const rangeCheck = (index: number, min: number, max: number, message = 'Index out of bounds.'): void => {
if (index < min || index > max) throw new RangeError(message);
}
export const throwRangeError = (message = 'The value is off-limits.'): void => {
throw new RangeError(message);
}
export const isObjOrFunc = (input: unknown): input is Record<string, unknown> | ((...args: any[]) => any) => {
const inputType = typeof input;
return (inputType === 'object' && input !== null) || inputType === 'function';
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc