typescript-ds-lib
Version:
A collection of TypeScript data structure implementations
126 lines • 3.79 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HashTable = void 0;
const hash_utils_1 = require("./hash-utils");
const base_collection_1 = require("./base-collection");
const utils_1 = require("./utils");
class HashNode {
key;
value;
next;
constructor(key, value) {
this.key = key;
this.value = value;
this.next = null;
}
}
class HashTable extends base_collection_1.BaseCollection {
table;
count;
capacity;
constructor(capacity = 4096) {
super();
// Handle negative or zero capacity by using default capacity
this.capacity = capacity <= 0 ? 4096 : capacity;
this.table = new Array(this.capacity).fill(null);
this.count = 0;
}
insert(key, value) {
const index = hash_utils_1.HashUtils.hash(key, this.capacity);
// Handle empty bucket case.
if (!this.table[index]) {
this.table[index] = new HashNode(key, value);
this.count++;
return;
}
// Check first node for key match. If it matches, update the value.
if (utils_1.Utils.equals(this.table[index].key, key)) {
this.table[index].value = value;
return;
}
// Traverse chain to find key or last node. If it matches, update the value.
let current = this.table[index];
while (current?.next) {
if (utils_1.Utils.equals(current.next.key, key)) {
current.next.value = value;
return;
}
current = current.next;
}
// Key not found, append new node.
current.next = new HashNode(key, value);
this.count++;
}
get(key) {
const index = hash_utils_1.HashUtils.hash(key, this.capacity);
let current = this.table[index];
while (current) {
if (utils_1.Utils.equals(current.key, key)) {
return current.value;
}
current = current.next;
}
return undefined;
}
remove(key) {
const index = hash_utils_1.HashUtils.hash(key, this.capacity);
let current = this.table[index];
let prev = null;
while (current) {
if (utils_1.Utils.equals(current.key, key)) {
if (prev) {
prev.next = current.next;
}
else {
this.table[index] = current.next;
}
this.count--;
return true;
}
prev = current;
current = current.next;
}
return false;
}
forEach(callback) {
for (const node of this.table) {
let current = node;
while (current) {
callback(current.key, current.value);
current = current.next;
}
}
}
size() {
return this.count;
}
isEmpty() {
return this.count === 0;
}
clear() {
this.table = new Array(this.capacity).fill(null);
this.count = 0;
}
/**
* Checks if two hash tables are equal.
*/
equals(other) {
if (!other || !(other instanceof HashTable)) {
return false;
}
if (this.size() !== other.size()) {
return false;
}
// Check each key-value pair in this table exists in other table
let isEqual = true;
this.forEach((key, value) => {
const otherValue = other.get(key);
if (!utils_1.Utils.equals(value, otherValue)) {
isEqual = false;
}
});
return isEqual;
}
}
exports.HashTable = HashTable;
//# sourceMappingURL=hash-table.js.map