Input:
getInputs =()=>[[2,2],[2,2],[1,2]]fn =function(a, b){return a + b;}Output: [{"val":4,"calls":1},{"val":4,"calls":1},{"val":3,"calls":2}]Explanation:
const inputs = getInputs();const memoized = memoize(fn);for(const arr of inputs){ memoized(...arr);}For the inputs of(2,2):2+2=4, and it required a call to fn().For the inputs of(2,2):2+2=4, but those inputs were seen before so no call to fn() was required.For the inputs of(1,2):1+2=3, and it required another call to fn()for a total of 2.
Input:
getInputs =()=>[[{},{}],[{},{}],[{},{}]]fn =function(a, b){return({...a,...b});}Output: [{"val":{},"calls":1},{"val":{},"calls":2},{"val":{},"calls":3}]Explanation:
Merging two empty objects will always result in an empty object. It may seem like there should only be 1 call to fn() because of cache-hits, however none of those objects are === to each other.
Input:
getInputs =()=>{const o ={};return[[o,o],[o,o],[o,o]];}fn =function(a, b){return({...a,...b});}Output: [{"val":{},"calls":1},{"val":{},"calls":1},{"val":{},"calls":1}]Explanation:
Merging two empty objects will always result in an empty object. The 2nd and 3rd third function calls result in a cache-hit. This is because every object passed inis identical.
To memoize a function for any type of arguments, we need to cache results based on argument identity (===). For primitive values, we can use a Map; for objects, we use a WeakMap to avoid memory leaks. We build a nested cache structure, where each argument leads to a new Map/WeakMap, and the result is stored at the final node.