-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathmemoize.js
61 lines (57 loc) · 1.8 KB
/
memoize.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import _enforceFunction from './internal/_enforceFunction';
import { Map, Seq } from 'immutable';
function defaultHashFunction(...args) {
if (args.length === 1) {
return args[0];
}
return Seq(args);
}
function memoized1(cache, operation, hashFunction, ...args) {
const key = hashFunction(...args);
if (!cache.has(key)) {
cache.set(key, operation(...args));
}
return cache.get(key);
}
function memoizedN(cache, operation, hashFunction, ...args) {
const key = hashFunction(...args);
if (!cache.has(key)) {
cache.set(key, operation(...args));
}
return cache.get(key);
}
/**
* Memoizer that uses a `Map` to allow for arbitrarily many/complex keys.
*
* @example
* const sum = memoize((list) => {
* return list.reduce((total, n) => total + n, 0);
* });
* // does work and returns 15
* sum(List.of(1, 2, 3, 4, 5))
* // returns 15 but does no work
* sum(List.of(1, 2, 3, 4, 5))
*
* @example <caption>We can use the `hashFunction` param to customize the key used in the cache.</caption>
* const sum = memoize(
* (list) => list.reduce((total, n) => total + n, 0),
* (list) => return list.join('-')
* );
*
* @example <caption>It's also possible to inspect the state of an instance by reading the `.cache` property.</caption>
*
* const sum = memoize(...);
* Map.isMap(sum.cache) === true;
*
* @param {Function} operation to memoize.
* @param {Function} hashFunction that generates the cache key.
* @return {Function} memoized version of `operation`.
*/
export default function memoize(operation, hashFunction = defaultHashFunction) {
_enforceFunction(operation);
const cache = Map().asMutable();
const memoizer = operation.length === 1 ? memoized1 : memoizedN;
const result = memoizer.bind(null, cache, operation, hashFunction);
result.cache = cache;
return result;
}