#Closures#Higher-Order Functions

Memoize

Cache a function by its arguments so the same call never computes twice.

By Pratik RaiMedium

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

Input:

JSfile.javascript
1const sum = memoize((a, b) => a + b); 2sum(2, 2); // 4, computed 3sum(2, 2); // 4, from cache 4sum.getCallCount();

Output:

1

The second call was served from the cache, so the original ran once.

Constraints

  • 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.

Goal: Serve repeat arguments from cache, and report the real call count.

Sources

Frequently asked questions

What is memoization?
Caching a function's result against its arguments so the same call never computes twice. It trades memory for time and only works for pure functions, where the same input always gives the same output.
Why check whether the cache has the key rather than the value?
Because `0`, `false`, `null`, `undefined` and `''` are all legitimate cached results and all falsy. `if (cache.get(key))` recomputes every one of them, which is the most common bug in a memoize implementation.
What is wrong with JSON.stringify as a cache key?
Key order changes the string, so two equal objects can produce different keys; functions and `undefined` disappear; and two genuinely different objects with the same shape collide. It is fine for numbers and strings and unreliable for anything else.
How would you memoize on argument identity instead?
With a tree of `Map`s, one level per argument, so lookup follows the actual references. That is exact but holds every argument alive forever unless you use `WeakMap`, which only accepts objects as keys.

Related Challenges

Continue learning with these related challenges

View All
JavaScript

Promisify a Callback Function

Convert a Node-style (error, value) callback API into one that returns a promise.

JavaScript · ES6Pratik Rai ·

JavaScript

Allow One Function Call

A once wrapper: the first call runs, every call after it does nothing.

JavaScript · ES6Pratik Rai ·

JavaScript

Infinite Curried Sum

sum(1)(2)(3) with no fixed arity — the running total appears when the result is coerced.

JavaScript · ES6Pratik Rai ·