大家好(不好称呼),
我有一个循环,每次通过时我都能得到四舍五入的差异。我想对其进行累加并将其添加到我的结果的最后一条记录中。
var cumulatedRoundDifference = 0m;
var resultSet = Enumerable.Range(0, periods)
.Select(currentPeriod => {
var value = this.CalculateValue(currentPeriod);
var valueRounded = this.CommercialRound(value);
// Bad part :(
cumulatedRoundDifference += value - valueRounded;
if (currentPeriod == periods - 1)
valueRounded = this.CommercialRound(value + valueRounded);
return valuesRounded;
}
目前,我认为代码还不太好。 对于这种事情是否有一种模式/算法,或者对于Linq来说,它是聪明的,而循环外没有变量?
许多问候
答案 0 :(得分:0)
您似乎正在做两件事-将所有内容四舍五入,然后计算总舍入误差。
您可以删除lambda之外的变量,但随后需要两个查询。
var baseQuery = Enumerable.Range(0, periods)
.Select(x => new { Value = CalculateValue(x), ValueRounded = CommercialRound(x) });
var cumulateRoundDifference = baseQuery.Select(x => x.Value - x.ValueRounded).Sum();
// LINQ isn't really good at doing something different to the last element
var resultSet = baseQuery.Select(x => x.ValueRounded).Take(periods - 1).Concat(new[] { CommercialRound(CalculateValue(periods - 1) + CommericalRound(periods - 1)) });
答案 1 :(得分:0)
Linq是否有用于这种事情的模式/算法,或者在循环外没有变量的情况下,它是不是很聪明?
我不太同意您要完成的工作。您正在尝试完成两个非常不同的任务,那么为什么要尝试将它们合并到同一迭代块中?后者(处理最后一项)甚至不应该是迭代。
出于可读性考虑,我建议将两者分开。这样做更有意义,不需要您检查是否在迭代的最后一个循环中(这可以节省一些代码和嵌套操作)。
虽然我不太了解计算本身,但是我可以回答您直接要求的算法(尽管我不确定这是最好的方法,我将在稍后解决在答案中。)
var allItemsExceptTheLastOne = allItems.Take(allItems.Count() - 1);
foreach(var item in allItemsExceptTheLastOne)
{
// Your logic for all items except the last one
}
var theLastItem = allItems.Last();
// Your logic for the last item
我认为这是一种更清洁,更易读的方法。我不喜欢将lambda方法用作可读性不高的迷你方法。这可能是主观的,而且是个人风格的问题。
在重读时,我认为我对计算有更好的了解,因此我尝试实现它,同时尽我所能最大限度地提高可读性:
// First we make a list of the values (without the sum)
var myValues = Enumerable
.Range(0, periods)
.Select(period => this.CalculateValue(period))
.Select(period => period - this.CommercialRound(period))
.ToList();
// myValues = [ 0.1, 0.2, 0.3 ]
myValues.Add(myValues.Sum());
// myValues = [ 0.1, 0.2, 0.3, 0.6 ]
这与我最初建议的算法相同:对可迭代项进行迭代,然后分别处理预期结果列表的最后一个值。
请注意,我将逻辑分为两个后续的Select
语句,因为我认为这是最易读(没有过多的lambda体)和有效的方式(没有重复的CalculateValue
调用)。但是,如果您更关注性能,例如当您希望处理大量列表时,可能需要再次合并它们。
我建议您始终尝试默认编写优于(过多)优化的可读性代码。并且仅在明显需要其他优化(我无法根据您的问题决定)的情况下才偏离该路径。
在第二次重读时,我不确定您是否已经对实际计算进行了足够的解释,因为cumulatedRoundDifference
并未真正用于您的计算中,但是代码似乎表明其值对于最终结果。