【发布时间】:2015-04-03 02:05:17
【问题描述】:
我从事淘汰赛已经 1 年多了,但仍有一个问题我无法解决。 这更像是“语法糖”问题,而不是实际问题。代码简单在 TypeScript 中,但应该没问题,即使你从未听说过。
让我解释一下。
假设我们有一个可观察数组(MyArray),其中每个元素都有“值”可观察。我们想创建一个计算的 observable 来获得所有的总和。
明显的方法是:
public SommeOne = ko.pureComputed((): number => {
var res = 0;
for (var i = 0; i < this.MyArray().length; i++) {
res += this.MyArray()[i].Value();
}
return res;
});
但是在这种情况下,对 this.MyArray() 的调用在每次迭代时都会被计算两次。和“价值”一次。这对于小数组(少于 1000 个元素)来说是可以的,但对于更大的数组来说就成了问题。所以,到目前为止我的解决方案是:
public SommeOne = ko.pureComputed((): number => {
var res = 0;
var array = this.MyArray();
for (var i = 0; i < array.length; i++) {
res += array[i].Value();
}
return res;
});
此时我们只评估 Array 函数一次(仍然是 1 次评估 Value,但没关系,我们需要这个)并且它工作正常。
所以最后一个问题:
如何在不创建中间“数组”的情况下实施第二种解决方案?
一个数组很好,但是如果你需要在两个数组之间做减法,或者更复杂的事情,这很快就会失控。
【问题讨论】:
-
您可以试验
Array#reduce或lodash 中的等效功能:this.MyArray().reduce((res, it) => res + it.Value(), 0)。但是,请记住,性能优化并不总是直观的,原生Array#reduce可能会很昂贵。在进行大量更改之前,分析您的代码以查看慢点在哪里。 -
嗯,我还没有听说过这个库。在我看来,这是一条可行的路。我对数组的调用将只评估一次。对于简单的情况,它会非常有用,但如果我需要在两个或多个数组之间进行交集或数据收集,它就会失败。至于分析,我正在做,就在今天,将所有 Date.parse 切换为 Date.parseExact,收益很大(大量数据,很多东西)。您可以将此作为答案发布,这将是我的起点。
-
做出决定后,您可以发布自我回答和 jsPerf 基准测试
-
所有提供的解决方案都是 O(n),所以我会选择最易读的。 (在我看来,_.reduce)
标签: javascript knockout.js typescript