我正在创建一个函数备忘录,返回一个函数,当调用它时,它将检查它是否已经计算了给定参数的结果,并在可能的情况下返回该值。
现在我的密钥只包含作为我的密钥传入的第一个参数,以检查函数是否已经运行。
const memo = function(func) {
const memoizedFunc = function () {
let result;
if (memoizedFunc.cache[arguments[0]] !== undefined) {
result = memoizedFunc.cache[arguments[0]];
} else {
result = func.apply(null, arguments);
memoizedFunc.cache[arguments[0]] = result;
}
return result;
}
memoizedFunc.cache = {};
return memoizedFunc;
};
所以如果我们使用测试函数运行它:
function memoAdd(num1, num2){
return num1 + num2;
}
memo(memoAdd(1, 2)));
memo(memoAdd(1, 3))); // -> since it's the first argument that we use as
// the key, it will still pull up 3 as the answer even if the answer should
// be four
任何想法我应该如何解决这个问题,以便我为不同的论点提供不同的结果?
答案 0 :(得分:1)
您的测试调用将失败,因为它没有将可调用对象传递给备忘录,而是函数的结果。
如果想法是为了避免重复计算而只返回相同的结果,你可以这样做:
var function_cache = {};
const memo1 = function(f, args) {
var sig = JSON.stringify(args);
if (f.cache == undefined) {
f.cache = {};
}
if (f.cache[sig] !== undefined) {
console.log('Value from Cache');
return f.cache[sig];
}
console.log('Value from Computation');
f.cache[sig] = f.apply(null, args);
return f.cache[sig];
}
function memoAdd(num1, num2){
return num1 + num2;
}
console.log(memo1(memoAdd, [1, 2]));
console.log(memo1(memoAdd, [1, 3]));
console.log(memo1(memoAdd, [1, 2]));
console.log(memo1(memoAdd, [1, 3]));
在这种情况下,散列cache
被添加到传递的函数中,并且参数通过JSON.stringify转换为字符串签名 - 用于查找先前值并返回它。
如果你的目标是有一个可调用的,这样你就不需要每次都把它包装在备忘录中,你可以调整一下:
const memo2 = function(f) {
if (f.cache == undefined) {
f.cache = {};
}
const newFunc = function() {
var sig = JSON.stringify(arguments);
if (f.cache[sig] !== undefined) {
console.log('Value from Cache');
return f.cache[sig];
}
console.log('Value from Computation');
f.cache[sig] = f.apply(null, arguments);
return f.cache[sig];
}
return newFunc;
}
function memoAdd(num1, num2){
return num1 + num2;
}
var myFunc = memo2(memoAdd);
console.log(myFunc(1,2));
console.log(myFunc(1,3));
console.log(myFunc(1,2));
console.log(myFunc(1,3));
在这种情况下,传入的函数被闭包锁定,我们仍然将结果缓存在f.cache中。