动机:
为了抽象,我有一个处理对象列表的方法。这里我展示了一个简化版本用于说明目的(在这里使用Python2.7):
def foo(obj_lst, f):
return list(map(f, obj_lst))
但是,对于某些情况,输入可能是foo([obj] * 1000, f)
,然后在函数调用中我必须重新计算1000次f(obj)。我们可以避免它,因为所有这些都是完全相同的对象。
我的解决方案:
我总是可以缓存计算结果,如
def foo2(obj_lst, f):
cache_map = {}
def foo_single(obj):
if id(obj) not in cache_map:
cache_map[id(obj)] = f(obj)
return cache_map[id(obj)]
result_lst = []
for obj in obj_lst:
result_lst.append(foo_single(obj))
return result_lst
这完全是我想要的工作,它确实可以加快重新计算开销。
我的问题:
这个解决方案对我来说还不够,因为我必须在每个函数中手动执行此操作,是否有更好的解决方案来避免一般"同一对象重新计算"对于非随机函数?具有来自函数id和所有参数的键的全局cache_map似乎不起作用,因为对象id在其生命周期内仅是唯一的。
一般来说,我理解这在Python中可能没有多大意义,因为这些对象是可变的。请问在Scala等函数式编程语言中是否存在一些处理不可变对象问题的现有方案?谢谢!
答案 0 :(得分:4)
您正在描述memoization。
这可以通过creating your own helper/decorator function或使用标准库中的functools.lru_cache来实现(Python 3.2 +)
答案 1 :(得分:0)
或许这样的事情?
foo(objectsWithDupes, Memoized(f))
然后你可以做(除了其他用途)validateInput: function (inputValue, inputName, inputRules, setFormState, formFields) {
let hasError = false;
let errorText = false;
if (!inputValue && inputRules.required) {
hasError = true;
errorText = 'This field is required.';
}
else {
hasError = false;
errorText = false;
};
state = { fields: Object.create(formFields) };
state.fields[inputName].hasError = hasError;
state.fields[inputName].errorText = errorText;
return setFormState(state);
}