Skip to content
JavaScript utilities · Core · about 15 minutes

Memoize

Implement memoize(fn, keyFn). It returns a function that remembers fn's result for each key and does not run fn again for a key it has seen. The key is keyFn(...args) when keyFn is given, otherwise the first argument. A remembered undefined is still a hit. Objects are keys by identity. The answer shows the results of the calls and how many times fn really ran.

Start from

function memoize(fn, keyFn) {
  // Return a function that caches fn's results by key.
}

Hints

Each hint gives away a little more. Open one only when you need it.

  1. Hint 1

    Use a Map for the cache: it keeps objects as keys by identity, where a plain object would turn them into the same string.

  2. Hint 2

    Check with cache.has(key), not with the value: a cached undefined would otherwise run fn again.

Solution

From here on the page gives the method away. If you are still solving, go back to the hints.

JavaScript
function memoize(fn, keyFn) {
  const cache = new Map();
  return function (...args) {
    const key = keyFn ? keyFn(...args) : args[0];
    if (cache.has(key)) return cache.get(key);
    const value = fn.apply(this, args);
    cache.set(key, value);
    return value;
  };
}

What an interviewer looks for

It is the idea behind useMemo and selector libraries. Interviewers look for the cache key decision and for the question you ask back: when is the cache cleared?