#️⃣ JavaScript Hashing Basics

Map vs Plain Object vs Set

// Map — any key type, preserves insertion order
const map = new Map();
map.set('apple', 3);
map.set(42, 'answer');
map.get('apple');   // 3
map.has('cherry');  // false
map.size;           // 2
map.delete('apple');

// Set — unique values, O(1) lookup
const set = new Set([1, 2, 2, 3]);
set.has(2);   // true
set.size;     // 3
set.add(4);
set.delete(2);

// Plain object — string/symbol keys only
const obj = {};
obj['key'] = 1;
'key' in obj; // true
delete obj['key'];

Frequency Counting

// Character frequency
function charFreq(s) {
    const freq = new Map();
    for (const c of s) freq.set(c, (freq.get(c) ?? 0) + 1);
    return freq;
}

// With plain object (slightly faster for small alphabets)
function charFreqObj(s) {
    const freq = {};
    for (const c of s) freq[c] = (freq[c] ?? 0) + 1;
    return freq;
}

Two-Sum Pattern

function twoSum(nums, target) {
    const map = new Map();
    for (let i = 0; i < nums.length; i++) {
        const comp = target - nums[i];
        if (map.has(comp)) return [map.get(comp), i];
        map.set(nums[i], i);
    }
    return [];
}

Prefix Sum with Map

function subarraySum(nums, k) {
    const prefixCount = new Map([[0, 1]]);
    let sum = 0, result = 0;
    for (const n of nums) {
        sum += n;
        result += prefixCount.get(sum - k) ?? 0;
        prefixCount.set(sum, (prefixCount.get(sum) ?? 0) + 1);
    }
    return result;
}

Common Map/Set Operations

OperationMapSetObject
Add/Setmap.set(k, v)set.add(v)obj[k]=v
Getmap.get(k)obj[k]
Has/Inmap.has(k)set.has(v)k in obj
Deletemap.delete(k)set.delete(v)delete obj[k]
Sizemap.sizeset.sizeObject.keys(obj).length
Iteratefor (const [k,v] of map)for (const v of set)for (const k in obj)

Complexity Summary

OperationAverageWorst
InsertO(1)O(n)
LookupO(1)O(n)
DeleteO(1)O(n)
SpaceO(n)O(n)

Prefer Map over plain objects when keys may be non-strings or when you need guaranteed insertion order.