Open In App

Hashing in JavaScript

Last Updated : 14 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Hashing is a popular technique used for storing and retrieving data as fast as possible. The main reason behind using hashing is:

  • It allows fast insertion, deletion, searching, and other operations.
  • In average cases, all these operations can be performed in O(1) (constant time).
  • In the worst case, the time complexity can be O(n), but on average it remains O(1).

Components of Hashing

Hashing consists of a hash table, which stores key-value pairs, and a hash function, which maps keys to indices for fast data retrieval. Collision handling resolves cases where multiple keys map to the same index.

jhn


1. Hash Table

A Hash Table is a data structure that stores data in key-value pairs. Think of it as an array where you use a key (like a string or number) to instantly find or store a value. A hash function turns the key into an array index, so you don’t have to search through the whole array. This makes searching for an element very efficient.

Example :

JavaScript
// Creating a simple hash table
let hashTable = {};

// Storing data: key-value pairs
hashTable["name"] = "Alice"; 
hashTable["age"] = 25;  


console.log(hashTable["name"]); 
console.log(hashTable["age"]);  

Output
Alice
25

Basic Hash Table Operations :

Let’s explore the core operations of a hash table in JavaScript with their syntax and explanations.

  • Insert : Adds a key-value pair to the hash table.
  • Get : Retrieves the value associated with a key.
  • Search : Checks if a value exists in the hash table.
  • Delete : Removes a key-value pair from the hash table.

Example :

JavaScript
class HashTable {
  constructor(size = 10) {
    this.table = new Array(size).fill(null); // Initialize with null
    this.size = 0; // Track number of entries
  }

  // Private hash function to convert key to index
  _hash(key) {
    return key % 10; // Simple modulo-based hash
  }

  // Insert a key-value pair
  insert(key, value) {
    const index = this._hash(key);
    this.table[index] = value;
    this.size++;
  }

  // Get value by key
  get(key) {
    const index = this._hash(key);
    return this.table[index] || null;
  }

  // Search for a value
  search(value) {
    for (let i = 0; i < this.table.length; i++) {
      if (this.table[i] === value) {
        console.log(`Value found at index: ${i}`);
        return;
      }
    }
    console.log("Value not found");
  }

  // Delete a key-value pair
  delete(key) {
    const index = this._hash(key);
    if (this.table[index]) {
      this.table[index] = null;
      this.size--;
      return true;
    }
    return false;
  }
}

// Example usage
const hashTable = new HashTable();

// Insert values
hashTable.insert(100, "Alice");
hashTable.insert(87, "Bob");
hashTable.insert(86, "Charlie");
hashTable.insert(12, "David");
hashTable.insert(9, "Eve");

console.log(hashTable.table); // [ 'Alice', <1 empty item>, 'David', <3 empty items>, 'Charlie', 'Bob', <1 empty item>, 'Eve' ]

// Search
hashTable.search("Bob"); // Value found at index: 7
hashTable.search("Frank"); // Value not found

// Delete
hashTable.delete(12);
console.log(hashTable.table); // [ 'Alice', <1 empty item>, null, <3 empty items>, 'Charlie', 'Bob', <1 empty item>, 'Eve' ]

Output
[
  'Alice',   null,
  'David',   null,
  null,      null,
  'Charlie', 'Bob',
  null,      'Eve'
]
Value found at index: 7
Value not found
[
  'Alice',   null,
  null,      null,
  null,      null,
 ...

2. Hash Function

The hash function is the heart of hashing. It takes a key (e.g., a number or string) and converts it into an index for the hash table. A good hash function:

  • Is fast to compute.
  • Distributes keys evenly across the table to avoid clustering.
  • Minimizes collisions (when two keys map to the same index).
  • Maintains a low load factor (the ratio of items to table size).

Example :

JavaScript
class LunchBoxWithLists {
  constructor() {
    this.slots = [[], [], [], [], [], [], [], [], [], []]; // 10 empty lists
  }

  // Hash function: Same as before
  _pickSlot(id) {
    return id % 10; // Example: 15 % 10 = 5
  }

  // Add a snack to a list in the slot
  add(id, snack) {
    const slot = this._pickSlot(id);
    this.slots[slot].push(snack); // Add to the list
    console.log(`Added ${snack} to slot ${slot}`);
  }

  // Find snacks in a slot
  find(id) {
    const slot = this._pickSlot(id);
    if (this.slots[slot].length > 0) {
      console.log(`Found ${this.slots[slot]} in slot ${slot}!`);
    } else {
      console.log(`Slot ${slot} is empty!`);
    }
  }
}

// Try it
const listBox = new LunchBoxWithLists();
listBox.add(15, "Apple"); // Slot 5
listBox.add(25, "Banana"); // Also slot 5
listBox.find(15); // Found Apple,Banana in slot 5!

Output
Added Apple to slot 5
Added Banana to slot 5
Found Apple,Banana in slot 5!

3. Collision Handling

Collisions happen when two keys map to the same index. For instance, if 100 and 10 both hash to index 0, you need a way to resolve this. Common techniques include:

  • Chaining: Each table slot holds a linked list of entries with the same hash. Simple but uses extra memory.
  • Open Addressing: Store all entries in the table itself by probing for the next available slot (e.g., linear probing).

Example 1 : Chaining

JavaScript
class HashTableWithChaining {
  constructor(size = 10) {
    this.table = new Array(size).fill().map(() => []); // Array of arrays
    this.size = 0;
  }

  _hash(key) {
    return key % 10;
  }

  insert(key, value) {
    const index = this._hash(key);
    this.table[index].push({ key, value });
    this.size++;
  }

  get(key) {
    const index = this._hash(key);
    const bucket = this.table[index];
    for (let item of bucket) {
      if (item.key === key) return item.value;
    }
    return null;
  }

  delete(key) {
    const index = this._hash(key);
    const bucket = this.table[index];
    for (let i = 0; i < bucket.length; i++) {
      if (bucket[i].key === key) {
        bucket.splice(i, 1);
        this.size--;
        return true;
      }
    }
    return false;
  }
}

// Example usage
const chainedHash = new HashTableWithChaining();
chainedHash.insert(100, "Alice");
chainedHash.insert(10, "Bob"); // Same index as 100
console.log(chainedHash.get(10)); // Bob
console.log(chainedHash.get(100)); // Alice

Output
Bob
Alice

Example 2 : Open Addressing

JavaScript
class HashTableWithProbing {
  constructor(size = 10) {
    this.table = new Array(size).fill(null); // Array for key-value pairs
    this.size = 0;
  }

  _hash(key) {
    return key % 10;
  }

  insert(key, value) {
    let index = this._hash(key);
    while (this.table[index] !== null) {
      index = (index + 1) % 10; // Linear probing
    }
    this.table[index] = { key, value };
    this.size++;
  }

  get(key) {
    let index = this._hash(key);
    let attempts = 0;
    while (attempts < this.table.length) {
      if (this.table[index] && this.table[index].key === key) {
        return this.table[index].value;
      }
      index = (index + 1) % 10; // Move to next slot
      attempts++;
    }
    return null;
  }
}

// Usage
const probedHash = new HashTableWithProbing();
probedHash.insert(100, "Alice");
probedHash.insert(10, "Bob"); 
console.log(probedHash.get(10)); 
console.log(probedHash.get(100)); 

Output
Bob
Alice

Introduction to Hashing
Visit Course explore course icon

Similar Reads