已有累积和极值计算的循环实现,如何改用LINQ实现?
用LINQ改写累积和最小/最大终端值计算
你可以通过两种方式实现:纯标准LINQ,或者借助MoreLINQ的Scan方法(这也是你提到的工具包的核心用法之一)。
一、标准LINQ实现
标准LINQ没有直接生成累积和的方法,我们可以用Aggregate收集每一步的累积结果,再计算极值:
public static Tuple<decimal, decimal> FindTerminalValues(IEnumerable<decimal> values) { // 用Aggregate生成所有累积和的序列 var cumulativeSums = values.Aggregate( new List<decimal>(), (acc, val) => { acc.Add(acc.Any() ? acc.Last() + val : val); return acc; }); // 计算累积和的最小/最大值,空序列时默认取0 decimal minSum = cumulativeSums.DefaultIfEmpty().Min(); decimal maxSum = cumulativeSums.DefaultIfEmpty().Max(); // 与初始基准0比较,得到最终的最小/最大终端值 return Tuple.Create(Math.Min(0, minSum), Math.Max(0, maxSum)); }
二、MoreLINQ实现
MoreLINQ的Scan方法专门用于生成累积运算的中间结果,代码会更简洁:
先通过NuGet安装MoreLinq包,然后实现:
using MoreLinq; public static Tuple<decimal, decimal> FindTerminalValues(IEnumerable<decimal> values) { // Scan直接生成累积和序列 var cumulativeSums = values.Scan((currentTotal, nextValue) => currentTotal + nextValue); decimal minSum = cumulativeSums.DefaultIfEmpty().Min(); decimal maxSum = cumulativeSums.DefaultIfEmpty().Max(); return Tuple.Create(Math.Min(0, minSum), Math.Max(0, maxSum)); }
逻辑说明
两种实现都严格对齐原循环的逻辑:
- 生成每一步的累积和序列
- 计算累积和的最小/最大值
- 与初始基准值
0比较,最终的最小终端值是0和累积和最小值中的较小者;最大终端值是0和累积和最大值中的较大者 - 空序列时返回
(0, 0),与原代码行为一致
内容的提问来源于stack exchange,提问作者morleyc
相关产品推荐
相关产品推荐

