Skip to content

Instantly share code, notes, and snippets.

@LucaColonnello
Last active March 17, 2022 10:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LucaColonnello/0df3922f892fe50ec2fa77d2e8aeefed to your computer and use it in GitHub Desktop.
Save LucaColonnello/0df3922f892fe50ec2fa77d2e8aeefed to your computer and use it in GitHub Desktop.
Memo higher order function that works with any number and type of params.
// https://jsbin.com/fumuwiqegu/edit?js,console
/*
Create a memo higher order function that works with any number and type of params.
This solution uses hashmaps to achieve fast performance.
cache = Map {
[[ValueSymbol]] => value,
arg1 => Map {
[[ValueSymbol]] => value,
arg2 => Map {
[[ValueSymbol]] => value,
},
arg3 => Map {
[[ValueSymbol]] => value,
}
}
}
*/
const ValueSymbol = Symbol("VALUE");
const NoValueYetSymbol = Symbol("NOVALUEYET");
function memo(f) {
const cacheResultByArgs = new Map();
const getFromCache = (args = [], cache = cacheResultByArgs) => {
if (args.length === 0) {
return cache.has(ValueSymbol) ? cache.get(ValueSymbol) : NoValueYetSymbol;
}
const [headArg, ...restArgs] = args;
return cache.has(headArg) ? getFromCache(restArgs, cache.get(headArg)) : NoValueYetSymbol;
};
const addResultToCache = (args = [], result, cache = cacheResultByArgs) => {
if (args.length === 0) {
cache.set(ValueSymbol, result);
return;
}
const [headArg, ...restArgs] = args;
if (!cache.has(headArg)) {
cache.set(headArg, new Map());
}
addResultToCache(restArgs, result, cache.get(headArg));
};
return (...args) => {
const cacheResult = getFromCache(args);
if (cacheResult !== NoValueYetSymbol) {
return cacheResult;
}
const result = f(...args);
addResultToCache(args, result);
return result;
};
}
// random test
const memoRandom = memo(Math.random);
console.log(memoRandom());
console.log(memoRandom());
console.log(memoRandom());
// random between test
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min) ) + min;
}
const memoGetRndInteger = memo(getRndInteger);
console.log(memoGetRndInteger(10, 100));
console.log(memoGetRndInteger(10, 100));
console.log(memoGetRndInteger(10, 100));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment