如何用单条LINQ语句计算平均值?现有代码优化咨询
嘿Tom,我来帮你搞定这个LINQ优化的问题!
最优实现:用LINQ内置的
Average一步到位 你现在的分步写法其实会三次遍历筛选后的集合(Where执行一次,Count和Sum又各执行一次),数据量大的时候这可不太高效。而LINQ早就给我们封装好了Average方法,既能一步算出平均值,又只需要一次遍历,绝对是最优解。
基础版直接替换
把你那四行代码换成这一行就够了:
var avgpremiumPaid = trigger2Output.NpvResults.CommIns .Where(x => x.layerId == 0) .Average(x => x.premPaid);
它会自动帮你完成筛选→求和→除以数量的全流程,而且全程只走一遍数据,比分步写法高效多了,代码也简洁不少。
处理空集合的坑
要是layerId == 0的记录有可能为空,直接调用Average会抛出InvalidOperationException(毕竟不能除以0嘛)。这时候可以加个DefaultIfEmpty来兜底,返回你想要的默认值(比如0):
var avgpremiumPaid = trigger2Output.NpvResults.CommIns .Where(x => x.layerId == 0) .Select(x => x.premPaid) .DefaultIfEmpty(0) .Average();
这样哪怕没有符合条件的记录,也会返回0而不是报错,代码更健壮。
为啥你的原写法不够优?
再说说你原来的分步代码:
var onlyLayer0 = trigger2Output.NpvResults.CommIns.Where(x => x.layerId == 0); var numberOfRecords = onlyLayer0.Count(); var totalPremiumPaid = onlyLayer0.Sum(x => x.premPaid); var avgpremiumPaid = totalPremiumPaid / numberOfRecords;
这里的onlyLayer0是延迟执行的IEnumerable,每次调用Count()和Sum()都会重新跑一遍Where的筛选逻辑——等于把数据遍历了三次!而Average只需要一次遍历,性能差距一下就出来了。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

