Dưới đây là triển khai hoàn chỉnh của class HashTable. Tất nhiên có thể cải tiến bằng cách dùng cấu trúc dữ liệu hiệu quả hơn và thuật toán giải quyết va chạm tốt hơn.
Ví dụ
class HashTable {
constructor() {
this.container = [];
// Khởi tạo container với các mảng rỗng
// dùng để thêm phần tử trong trường hợp va chạm
for (let i = 0; i < 11; i++) {
this.container.push([]);
}
}
display() {
this.container.forEach((value, index) => {
let chain = value
.map(({ key, value }) => `{ ${key}: ${value} }`)
.join(" --> ");
console.log(`${index}: ${chain}`);
});
}
put(key, value) {
let hashCode = this.hash(key);
for (let i = 0; i < this.container[hashCode].length; i++) {
// Thay thế giá trị hiện tại bằng khóa cho trước
// nếu nó đã tồn tại
if (this.container[hashCode][i].key === key) {
this.container[hashCode][i].value = value;
return;
}
}
// Thêm cặp vào cuối mảng
this.container[hashCode].push(new this.KVPair(key, value));
}
get(key) {
let hashCode = this.hash(key);
for (let i = 0; i < this.container[hashCode].length; i++) {
// Tìm phần tử trong chain
if (this.container[hashCode][i].key === key) {
return this.container[hashCode][i];
}
}
return undefined;
}
remove(key) {
let hashCode = this.hash(key);
for (let i = 0; i < this.container[hashCode].length; i++) {
// Tìm phần tử trong chain
if (this.container[hashCode][i].key === key) {
this.container[hashCode].splice(i, 1);
return true;
}
}
return false;
}
hash(key) {
return key % 11;
}
forEach(callback) {
// Với mỗi chain
this.container.forEach(elem => {
// Với mỗi phần tử trong chain gọi callback trên cặp KV
elem.forEach(({ key, value }) => callback(key, value));
});
}
static join(table1, table2) {
// Kiểm tra cả 2 tham số có phải HashTable không
if (!table1 instanceof HashTable || !table2 instanceof HashTable) {
throw new Error("Illegal Arguments");
}
let combo = new HashTable();
table1.forEach((k, v) => combo.put(k, v));
table2.forEach((k, v) => combo.put(k, v));
return combo;
}
}
HashTable.prototype.KVPair = class {
constructor(key, value) {
this.key = key;
this.value = value;
}
};