Last active
March 17, 2022 10:27
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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