Memoize
Write memoize(fn) returning a function that behaves identically but never recomputes for arguments it has already seen.
The returned function also exposes getCallCount(), reporting how many times the original actually ran.
Examples
const sum = memoize((a, b) => a + b);
sum(2, 2); // 4, computed
sum(2, 2); // 4, from cache
sum.getCallCount();1Constraints
- Arguments are JSON-serialisable
Notes
- A cached `0`, `false` or `undefined` is still a cached value — check whether the key exists, not whether the value is truthy.
- The harder version (LeetCode 2630) keys on argument identity, which rules out JSON.stringify entirely.
Hints
Memoize (reference solution)
One way to do it. The Editorial tab walks through why it is written this way.
Solution
1function memoize(fn) {
2 const cache = new Map();
3 let callCount = 0;
4 const memoized = function (...args) {
5 const key = JSON.stringify(args);
6 if (cache.has(key)) return cache.get(key);
7 callCount += 1;
8 const value = fn.apply(this, args);
9 cache.set(key, value);
10 return value;
11 };
12 memoized.getCallCount = () => callCount;
13 return memoized;
14}Editorial: Memoize
Trading memory for time
Memoisation is a cache keyed by arguments. The interesting parts are not the caching but the two places it quietly goes wrong.
Approach
A Map from a key derived from the arguments to the result.
Implementation
function memoize(fn) { const cache = new Map(); let callCount = 0; const memoized = function (...args) { const key = JSON.stringify(args); if (cache.has(key)) return cache.get(key); callCount += 1; const value = fn.apply(this, args); cache.set(key, value); return value; }; memoized.getCallCount = () => callCount; return memoized; }
Worth knowing
Check for the key, not the value. if (cache.get(key)) recomputes every cached 0, false, null and undefined. cache.has(key) is the correct test, and the suite checks it with a function that returns 0.
JSON.stringify is a lossy key. Key order changes the string, so {a:1,b:2} and {b:2,a:1} become different entries; functions and undefined vanish; two distinct objects with the same shape collide. The harder follow-up (LeetCode 2630) keys on argument identity using a tree of Maps, one level per argument, which is exact but never releases what it holds.