繁体   English   中英

lambda表达式foreach循环

[英]lambda expression foreach loop

我有以下代码

int someCount = 0;

for ( int i =0 ; i < intarr.Length;i++ )
{
   if ( intarr[i] % 2 == 0 )
   { 
       someCount++;
       continue;
   }
   // Some other logic for those not satisfying the condition
}

是否可以使用Array.Where或Array.SkiplWhile中的任何一个来实现相同目的?

foreach(int i in intarr.where(<<condtion>> + increment for failures) )
{
      // Some other logic for those not satisfying the condition    
}

使用LINQ:

int someCount = intarr.Count(val => val % 2 == 0);

我绝对更喜欢@nneonneo的短语句方式(它使用显式lambda),但是如果您要构建更复杂的查询,则可以使用LINQ查询语法

var count = ( from val in intarr 
    where val % 2 == 0 
    select val ).Count();

显然,当查询可以使用单个lambda表达式表示时,这可能是一个糟糕的选择,但是我发现在组成较大的查询时它很有用。

更多示例: http : //code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

没有什么(多)阻止你滚你自己Where才是最重要的失败。 “没什么”,因为lambda和带有yield return语句的方法均不允许引用out / ref参数, 因此具有以下签名的所需扩展名将无效

// dead-end/bad signature, do not attempt
IEnumerable<T> Where(
    this IEnumerable<T> self,
    Func<T,bool> predicate,
    out int failures)

但是,我们可以为失败计数声明一个局部变量,然后返回可以获取失败计数的Func<int> ,并且局部变量对于从lambda引用完全有效。 因此,这是一个可能的(经过测试的)实现:

public static class EnumerableExtensions
{
    public static IEnumerable<T> Where<T>(
        this IEnumerable<T> self,
        Func<T,bool> predicate,
        out Func<int> getFailureCount)
    {
        if (self == null) throw new ArgumentNullException("self");
        if (predicate == null) throw new ArgumentNullException("predicate");

        int failures = 0;

        getFailureCount = () => failures;

        return self.Where(i =>
            {
                bool res = predicate(i);
                if (!res)
                {
                    ++failures;
                }
                return res;
            });
    }
}

...这是一些练习它的测试代码:

Func<int> getFailureCount;
int[] items = { 0, 1, 2, 3, 4 };
foreach(int i in items.Where(i => i % 2 == 0, out getFailureCount))
{
    Console.WriteLine(i);
}
Console.WriteLine("Failures = " + getFailureCount());

以上测试,运行时输出:

0
2
4
失败= 2

我有一些警告需要警告。 由于您可能会在不遍历整个IEnumerable<>情况下过早地退出循环,因此故障计数将仅反映遇到的故障,而不是@nneonneo解决方案(我更喜欢)中的故障总数 LINQ的Where扩展的实现将以谓词对每个项目多次调用的方式进行更改,那么失败计数将是不正确的。 另一个有趣的地方是,您应该可以从循环体内调用getFailureCount Func以获得到目前为止的当前运行失败计数。

我介绍了此解决方案,以表明我们并未锁定现有的预打包解决方案。 语言和框架为我们提供了很多机会来扩展它以适应我们的需求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM