LRU Cache
A Least Recently Used cache evicts the entry that hasn’t been touched for the longest time once it hits capacity. Map makes this an O(1), few-line implementation in TypeScript: JS Map preserves insertion order, so “most recently used” = re-insert at the end, and “least recently used” = the first key keys().next() yields.
class LRUCache<K, V> {
private cache = new Map<K, V>();
constructor(private readonly capacity: number) {}
get(key: K): V | undefined {
if (!this.cache.has(key)) return undefined;
const value = this.cache.get(key)!;
this.cache.delete(key); // re-insert to mark most-recently-used
this.cache.set(key, value);
return value;
}
set(key: K, value: V): void {
if (this.cache.has(key)) {
this.cache.delete(key); // move to end
} else if (this.cache.size >= this.capacity) {
const lruKey = this.cache.keys().next().value as K; // oldest = first inserted
this.cache.delete(lruKey);
}
this.cache.set(key, value);
}
}Why Map, not a plain object
- Insertion order is guaranteed and iterable —
keys().next().valueis the eviction candidate in O(1). - Keys keep their type (objects, numbers) instead of being coerced to strings.
delete+setis the idiomatic “bump to most-recent” move.
Memoization Example
const memo = new LRUCache<number, number>(100_000);
function fib(n: number): number {
if (n <= 1) return n;
const hit = memo.get(n);
if (hit !== undefined) return hit;
const result = fib(n - 1) + fib(n - 2);
memo.set(n, result);
return result;
}Where this sits
This is the in-process variant of the cache-aside pattern in Caching. For anything shared across processes or hosts, reach for Redis / Memcached instead of an in-memory
Map.