#️⃣ 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
| Operation | Map | Set | Object |
| Add/Set | map.set(k, v) | set.add(v) | obj[k]=v |
| Get | map.get(k) | — | obj[k] |
| Has/In | map.has(k) | set.has(v) | k in obj |
| Delete | map.delete(k) | set.delete(v) | delete obj[k] |
| Size | map.size | set.size | Object.keys(obj).length |
| Iterate | for (const [k,v] of map) | for (const v of set) | for (const k in obj) |
Complexity Summary
| Operation | Average | Worst |
| Insert | O(1) | O(n) |
| Lookup | O(1) | O(n) |
| Delete | O(1) | O(n) |
| Space | O(n) | O(n) |
Prefer Map over plain objects when keys may be non-strings or when you need guaranteed insertion order.