Skip to content

Instantly share code, notes, and snippets.

@Javran
Created July 3, 2017 03:54
Show Gist options
  • Select an option

  • Save Javran/a01faa7712106dc6c0e71fa6fff6a4f4 to your computer and use it in GitHub Desktop.

Select an option

Save Javran/a01faa7712106dc6c0e71fa6fff6a4f4 to your computer and use it in GitHub Desktop.
memoize using nested Map assuming fixed function arity
// `deepWrite(map)([k1,k2,k3...])(value)`
// - assigns `value` to `map.get(k1).get(k2).get(k3)...`.
// - new Map objects are created if some key is missing along the path.
// - INVARIANT: keys.length >= 1
const deepWrite = map => keys => value => {
if (keys.length === 0) {
console.error(`invariant violation: empty key array`)
return undefined
}
if (keys.length === 1) {
const [key] = keys
map.set(key,value)
return map
} else {
const [key, ...ks] = keys
const subMap = map.has(key) ? map.get(key) : new Map()
const subMapAfter = deepWrite(subMap)(ks)(value)
map.set(key,subMapAfter)
return map
}
}
const deepLookup = map => keys => {
if (keys.length === 0) {
return map
}
const [key, ...restKeys] = keys
return map.has(key) ?
deepLookup(map.get(key))(restKeys) :
undefined
}
const deepMapToObject = map => {
if (map instanceof Map) {
const obj = {}
map.forEach((v,k) => {
obj[k] = deepMapToObject(v)
})
return obj
} else {
return map
}
}
const memoizeFixedArity = arity => func => {
if (typeof arity !== 'number' || arity <= 0) {
console.warn(`invariant violation: arity should be a positive number`)
// in this case we just leave the function intact and return it.
return func
}
let cache = new Map()
return (...args) => {
if (args.length !== arity) {
console.warn(`arity mismatched, skipping cache lookup.`)
return func(...args)
}
const cached = deepLookup(cache)(args)
if (typeof cached === 'undefined') {
const result = func(...args)
cache = deepWrite(cache)(args)(result)
return result
} else {
return cached
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment