patternjavascriptMinor
Elegant memoizing
Viewed 0 times
memoizingelegantstackoverflow
Problem
I wanted an elegant way to implement memoizing. Here is what I came up with:
It's quite nice, but the WeakMap is not well supported. Is there a better, yet clean way to do this?
function memoize(fn) {
var cache = new WeakMap();
return function() {
if (!cache[arguments]) {
cache[arguments] = fn.call(this, arguments);
}
return cache[arguments];
}
}It's quite nice, but the WeakMap is not well supported. Is there a better, yet clean way to do this?
Solution
I use this
this function will memoize the result of the function you pass and cache it. The cache will vary on the first argument, and only on the first argument. Do not use this function if you are planning on passing more then one argument to it! Do use this function if you want to pass an object as the first argument.
I use this function for building (temporary) indexes based on an immutable state. Example (the groupBy, where methods come from IxJS):
Because the state is immutable, it will not change. The only way to change the state is to create a new one. So everytime something changes, we have a new state. That makes is an excellent cache key!
function memoizeFirst(fn) {
const cache = new WeakMap();
return function(arg) {
if (!cache.has(arg)) {
cache.set(arg, fn(arg));
}
return cache.get(arg);
};
}this function will memoize the result of the function you pass and cache it. The cache will vary on the first argument, and only on the first argument. Do not use this function if you are planning on passing more then one argument to it! Do use this function if you want to pass an object as the first argument.
I use this function for building (temporary) indexes based on an immutable state. Example (the groupBy, where methods come from IxJS):
const getParentObjectIndex = memoizeFirst(state => state.objectSource && state.objectSource.
where(objectItem => objectItem.parentObject).
groupBy(objectItem => objectItem.parentObject).
reduce(function(map, group) {
map[group.key] = group.
orderBy(item => item.position).
toArray();
return map;
}, {})
);Because the state is immutable, it will not change. The only way to change the state is to create a new one. So everytime something changes, we have a new state. That makes is an excellent cache key!
Code Snippets
function memoizeFirst(fn) {
const cache = new WeakMap();
return function(arg) {
if (!cache.has(arg)) {
cache.set(arg, fn(arg));
}
return cache.get(arg);
};
}const getParentObjectIndex = memoizeFirst(state => state.objectSource && state.objectSource.
where(objectItem => objectItem.parentObject).
groupBy(objectItem => objectItem.parentObject).
reduce(function(map, group) {
map[group.key] = group.
orderBy(item => item.position).
toArray();
return map;
}, {})
);Context
StackExchange Code Review Q#21192, answer score: 4
Revisions (0)
No revisions yet.