3

同じ行の Linq メソッドから以前の値にアクセスする方法を見つけようとしています。

Linq でこの一般的な形式を使用できるようにしたい:

var values = Enumerable.Range( 1, 100 ).Select( i => i + [last result] );

しかし、複数行のラムダを使用せずに結果を別の場所に保存しないと、このようなことを行う方法を見つけることができません。

したがって、Linq で実行できる最高のフィボナッチ和は次のとおりです。

List<int> calculated = new List<int>( new int[] { 1, 2 });
var fibonacci = Enumerable.Range(2, 10).Select(i =>
    {
        int result = calculated[i - 2] + calculated[i - 1];
        calculated.Add(result);
        return result; // and how could I just put the result in fibonacci?
    }
);

これは醜いようです。通常の for ループを使用すると、より少ないコードでこれを行うことができます。

for (int i = 2; i < 10; i++)
{
    calculated.Add(calculated[i - 2] + calculated[i - 1]);
}

これを行う方法を見つけることができれば、Linq を使用して多くの線形プログラミングを実行し、多くの反復式を合計できるようです。

4

2 に答える 2

6

フィボナッチ数列ジェネレーターを作成する方法を探している場合は、Linq 拡張メソッドを使用する代わりに、独自のジェネレーター関数を作成することをお勧めします。このようなもの:

public static IEnumerable<int> Fibonacci()
{
    int a = 1;
    int b = 0;
    int last;

    for (;;) {
        yield return a;

        last = a;
        a += b;
        b = last;
    }
}

次に、Linq メソッドをこの列挙型に適用して、必要な結果を得ることができます (Fibonacci().Take(20)たとえば、反復処理を試してください)。

Linq 拡張メソッドはすべてのプログラミングの問題を解決できるわけではなく、純粋な LINQ フィボナッチ数列ジェネレーターがどれほど恐ろしいものになるか想像することしかできません。

于 2012-12-26T21:15:52.777 に答える
1

LINQ でそのようなことに最も近いのは、IEnumerable.Aggregateメソッド (関数型プログラミングのフォールド) です。たとえば、次のようにコレクションの二乗を合計するために使用できます。

int sumSquares = list.Aggregate(0, (sum, item) => sum + item * item);

LINQ では、値は列挙子を使用してコレクションから取得されるため、つまり値は 1 つずつ取得されるため、定義上、「前の項目」という概念はありません。yield returnいくつかの魔法を使用して、アイテムをその場で生成および破棄することもできます。とはいえ、次のようなハックをいつでも使用できます。

long a= 1;
long b= 1;
var fibonacci = Enumerable.Range(1,20).Select(i => {
  long last= a + b;
  b = a;
  a = last;
  return last;
});

しかし、ラムダを機能させるために外部変数を使用および変更する必要がある瞬間は、コード臭の領域にいます。

于 2012-12-26T21:15:35.257 に答える