2

つまり、Linqの結合、グループ化、個別化などと同様に、コレクションではなく、値のシーケンスのみを処理することを意味します。

シーケンスとコレクションの違いは、シーケンスの長さが無限であるのに対し、コレクションは有限である可能性があることです。

例を挙げましょう:

var c1 = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var c2 = FunctionThatYieldsFibonacciNumbers();

var c3 = c1.Except(c2);

これは動作しません。Exceptの実装は、いずれかのコレクションの数値が厳密に昇順または降順であることに基づいて機能しないため、最初に2番目のコレクションからすべての値をセット(または同様のもの)に収集しようとし、その後でのみ実行されます。最初のコレクションの列挙を開始します。

上記の関数が、明示的に列挙を停止しない限り終了しないWhileループであると仮定すると、上記のコードはメモリ不足の例外で失敗します。

しかし、厳密に昇順または降順であると見なされるコレクションがあることを考えると、.NET4.0にすでに実行できる実装はありますか。

  1. 両方に共通するすべての値を教えてください(内部結合)
  2. 両方のすべての値を教えてください(ユニオン/外部結合)
  3. シーケンス#2にないシーケンス#1のすべての値を教えてください

構築する必要のあるスケジューリングシステムに関連するこのタイプの機能が必要です。ここでは、次のようなことを行う必要があります。

c1=2010年1月以降の毎月1日と15日
c2=2010年以降の平日
c3 = 2010〜2012年のすべての日
c4=c1およびc2およびc3

これは基本的に、2010年から2012年まで毎月1日と15日ごとに与えられますが、それらの日付が平日に当たる場合に限ります。

このような関数を使用すると、コレクションを明示的に作成しなくても、問題の値を生成するのがはるかに簡単になります。上記の例では、最初の2つのコレクションを作成するには、3番目のコレクションの制約を知る必要があり、例は上記よりもはるかに複雑になる可能性があります。

4

2 に答える 2

2

LINQ演算子はすでに一般的なシーケンスで機能していると思いますが、ここにある単調なシーケンスで特に機能するようには設計されていません。

そのようなことを書くのはそれほど難しいことではないだろうと私は思うが、何も組み込まれているとは思わない。私が見る限り、System.Interactiveにはこのシナリオには何もありません。

于 2010-06-29T07:58:44.930 に答える
1

シーケンスを生成するような特別なF#言語構造を使用して自動的に呼び出される、F#のSeqモジュールを検討することができます。遅延評価が可能になるため、記述した方法で無限シーケンス1 .. 10をサポートします。F#の使用は、状況によっては簡単な場合とそうでない場合があります。ただし、C#から直接Seqモジュールを使用するのはそれほど難しいことではありません(ただし、私自身は試していません)。

このマンデルブロの例に続いて、を非表示にすることにより、C#で無限シーケンスを使用する方法を示しますyield。それがあなたが望むものにあなたを近づけるかどうかはわかりませんが、それは役立つかもしれません。

編集
あなたはすでにあなたの現在のプロジェクトでは価値がないとコメントし、あなたの質問への答えを受け入れましたが、私はそのアイデアに興味をそそられ、小さな例を思いつきました。

FSharp.Core.dll(.NET 3.5用にダウンロード)を参照に含めるだけで、それはかなり些細なことのように見え、.NET3.5および.NET4.0のC#でうまく機能します。これは、最初のユースケースを実装する無限シーケンスのすぐに使える例です。

// place in your using-section:
using Microsoft.FSharp.Collections;
using Microsoft.FSharp.Core;

// [...]

// trivial 1st and 15th of the month filter, starting Jan 1, 2010.
Func<int, DateTime> firstAndFifteenth = (int i) =>
{
    int year = i / 24 + 2010;
    int day = i % 2 != 0 ? 15 : 1;
    int month = ((int)i / 2) % 12 + 1;
    return new DateTime(year, month, day);
};

// convert func to keep F# happy
var fsharpFunc = FSharpFunc<int, DateTime>.FromConverter(
                   new Converter<int, DateTime>(firstAndFifteenth));

// infinite sequence, returns IEnumerable
var infSeq = SeqModule.InitializeInfinite<DateTime>(fsharpFunc);

// first 100 dates
foreach (var dt in infSeq.Take(100))
    Debug.WriteLine("Date is now: {0:MM-dd-yyy}", dt);

出力は期待どおりで、最初の数行は次のようになります。

現在の日付:2010年1月1日
現在の日付:2010年1月15日
現在の日付:2010年2月1日
現在の日付:2010年2月15日
現在の日付:2010年3月1日
于 2010-06-29T08:12:52.543 に答える