1

私は次のコードを持っています

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    
}
4

3 に答える 3

6

LINQを使用する:

int someCount = intarr.Count(val => val % 2 == 0);
于 2012-09-08T01:43:35.137 に答える
3

私は間違いなく@nneonneoの短いステートメントの方法を好みます(そしてそれは明示的なラムダを使用します)が、より複雑なクエリを構築したい場合は、LINQクエリ構文を使用できます:

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

クエリを単一のラムダ式で表現できる場合、これはおそらく適切な選択ではありませんが、より大きなクエリを作成する場合には便利です。

その他の例:http ://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

于 2012-09-08T01:45:10.560 に答える
0

Where失敗を数えるあなた自身を転がすことを妨げるものは何もありません。ラムダもステートメントを含むメソッドもout/refパラメーターを参照できないため、 「何もありません」。そのため、次のシグネチャを持つ目的の拡張機能は機能しませんyield return

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

ただし、failure-countのローカル変数を宣言して、failure-countを取得できるaを返すFunc<int>ことはできます。ローカル変数は、ラムダからの参照に対して完全に有効です。したがって、可能な(テスト済みの)実装は次のとおりです。

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());

上記のテスト、実行時の出力:

024 失敗=
2

警告しなければならないと感じる警告がいくつかあります。全体を歩かなくてもループから途中で抜け出す可能性があるため、失敗数は発生した失敗のみを反映し、 @ nneonneoのソリューション(私が好む)のIEnumerable<>ように失敗の総数は反映しません。また、LINQの実装の場合拡張機能は、アイテムごとに述語を複数回呼び出す方法で変更された場合、失敗数は正しくありません。もう1つの興味深い点は、ループ本体内からgetFailureCount Funcを呼び出して、これまでの実行中の障害カウントを取得できるようにする必要があることです。Where

このソリューションを提示して、既存のパッケージ済みソリューションに縛られていないことを示しました。言語とフレームワークは、私たちのニーズに合わせてそれを拡張する多くの機会を私たちに提供します。

于 2012-09-08T05:28:20.420 に答える