我有一个大型数据集合,我经常通过首先应用过滤器来查询。我想缓存并重用我使用的不同过滤器函数的结果,因为这部分可能很昂贵。这是对此的粗略模拟:
const a = x => x + 1;
const b = x => x + 2;
const m = _.memoize(
f => (console.log('filtering data'), f(314159)),
f => String(f)
);
console.log(m(a));
console.log(m(b));
console.log(m(a));
console.log(m(b));
这里“a”和“b”是我想要使用的过滤器功能,“m”每次都对相同的数据起作用。
如何指定_.memoize函数的键?
上面的工作,但我正在使用感觉错误的函数的字符串表示。还有更好的方法吗?
我担心在应用缩小时这不安全。在我的实际代码中,“memoize”部分在一个ES6模块中,“a”和“b”部分在另一个模块中,对“m”的调用在几个不同的模块中导入“a”和“b” “功能。这样的模块之间的字符串表示是否稳定?是否快速转换为字符串表示?
我能想到的唯一选择是创建一个字符串 - >函数字典,所以你可以像m(“a”)那样进行调用,但如果名称错误,则不能使用JavaScript链接。
答案 0 :(得分:2)
以上是有效的,但我正在使用感觉错误的函数的字符串表示。
确实
我担心在应用缩小时这不安全。
不,缩小不是问题。不同的函数被缩小为不同的代码。
问题是关闭:
const addTo = x => y => x + y
const a = addTo(1),
b = addTo(2);
console.log(String(a) === String(b));
您只能通过对象标识可靠地比较函数。最好的方法可能是更新Lodash以使用不需要任何字符串化的ES6 WeakMap
。
只要没有,您可以使用
const id = Symbol("function identity");
let count = 0;
function toMemoizeKey(fn) {
return fn[id] || (fn[id] = ++count);
}