You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用LINQ改写迭代算法避免重复计算?支持MoreLINQ方案

如何用LINQ改写避免重复计算的迭代算法?

现有如下迭代算法,需要用LINQ改写,同时避免重复调用ComplicatedCalculation()方法:

int GetMatchingValue(List<Thing> things)
{
 foreach(Thing t in things)
 {
  var value = t.ComplicatedCalculation();
  if(value > 0)
   return value;
 }
 return 0;
}

直接用FirstOrDefault筛选Thing会导致重复调用计算方法,因此需要调整LINQ写法来避免这个问题。

原生LINQ解决方案(无重复计算)

核心思路是先投影计算结果,再筛选,这样每个Thing只会调用一次ComplicatedCalculation(),且找到第一个符合条件的值后立即停止遍历(短路求值),和原迭代逻辑完全一致:

int GetMatchingValue(List<Thing> things)
{
    // 先投影出所有计算值,再取第一个>0的,无符合项则返回int默认值0
    return things.Select(t => t.ComplicatedCalculation())
                 .FirstOrDefault(v => v > 0);
}

如果ComplicatedCalculation()返回的是可空类型(比如int?),可以用空合并运算符兜底:

int GetMatchingValue(List<Thing> things)
{
    return things.Select(t => t.ComplicatedCalculation())
                 .FirstOrDefault(v => v.HasValue && v.Value > 0) ?? 0;
}

原迭代方案的定位

原迭代写法本身已经非常简洁直观,尤其是如果后续需要扩展逻辑(比如同时返回Thing实例和计算值),迭代写法的可读性和灵活性会更强。但如果只是单纯返回符合条件的计算值,上述LINQ写法同样紧凑高效,且代码更具声明式风格。

MoreLINQ实现方案

如果项目中引入了MoreLINQ库,可以利用其FirstOr方法更明确地指定默认值(即使返回类型的默认值不是0也能直接定义):

using MoreLinq;

int GetMatchingValue(List<Thing> things)
{
    return things.Select(t => t.ComplicatedCalculation())
                 .FirstOr(v => v > 0, 0);
}

另外,MoreLINQ的TryFirst方法也可以实现类似逻辑,适合需要明确判断是否找到符合项的场景:

using MoreLinq;

int GetMatchingValue(List<Thing> things)
{
    if (things.Select(t => t.ComplicatedCalculation())
              .TryFirst(v => v > 0, out var result))
    {
        return result;
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Mr. Boy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:50:34