นี่คือการนำ HashTable class ไปใช้งานอย่างสมบูรณ์ ซึ่งยังสามารถปรับปรุงได้โดยใช้ data structures และ collision resolution algorithms ที่มีประสิทธิภาพมากขึ้น
ตัวอย่างโค้ด
class HashTable {
constructor() {
this.container = [];
// เติม container ด้วย array ว่างๆ
// สำหรับเพิ่ม elements ในกรณี collision
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++) {
// แทนที่ค่าที่มีอยู่กับคีย์ที่กำหนดถ้ามีอยู่แล้ว
if (this.container[hashCode][i].key === key) {
this.container[hashCode][i].value = value;
return;
}
}
// เพิ่มคู่ข้อมูลที่ปลาย array
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++) {
// ค้นหา element ใน 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++) {
// ค้นหา element ใน 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) {
// สำหรับแต่ละ chain
this.container.forEach(elem => {
// สำหรับแต่ละ element ในแต่ละ chain เรียก callback กับคู่ KV
elem.forEach(({ key, value }) => callback(key, value));
});
}
static join(table1, table2) {
// ตรวจสอบว่าทั้งสอง args เป็น HashTables
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;
}
};