私はList/IEnumerableをとり、連続したデータのまとまりを扱う必要がある移動平均のような問題を扱うC#コードを作成しています。 F#Seqモジュールは、シーケンスを取る大きな関数を持っていて、連続した要素のチャンクのシーケンスを返します。F#Seq.windowedと同等のものがC#にありますか?
C#には、LINQと同等の機能がありますか?
私はList/IEnumerableをとり、連続したデータのまとまりを扱う必要がある移動平均のような問題を扱うC#コードを作成しています。 F#Seqモジュールは、シーケンスを取る大きな関数を持っていて、連続した要素のチャンクのシーケンスを返します。F#Seq.windowedと同等のものがC#にありますか?
C#には、LINQと同等の機能がありますか?
いつでもSeqModule.Windowed
をC#から呼び出すことができます。ちょうどFSharp.Core.Dll
を参照する必要があります。関数名もわずかマングルされているので、それはC#の総額規則に合うように、あなたは常に独自のロール(またはF#のコアから1変換する)ことができ
ここ、ここで、いつもそれをやって! Seq.singleton、FSharpSet、名前を付けます。 C#でコードを作成する必要があるときは、F#stdlibを使用することがよくあります。それがなければ、どうすれば私は生きることができますか – kkm
実際には 'SeqModule.Windowed'です。 –
、windowed
ではなくWindowed
を呼び出す:
let windowed windowSize (source: seq<_>) =
checkNonNull "source" source
if windowSize <= 0 then invalidArg "windowSize" (SR.GetString(SR.inputMustBeNonNegative))
seq { let arr = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked windowSize
let r = ref (windowSize-1)
let i = ref 0
use e = source.GetEnumerator()
while e.MoveNext() do
arr.[!i] <- e.Current
i := (!i + 1) % windowSize
if !r = 0 then
yield Array.init windowSize (fun j -> arr.[(!i+j) % windowSize])
else
r := (!r - 1) }
を
私の試みはこのように見えますが、それはF#を直接呼び出すよりも遅いです(John Palmerの示唆)。私はそれが未確認のアレイを使用しているためのF#のだ推測している。:
public static IEnumerable<T[]> Windowed<T>(this IEnumerable<T> list, int windowSize)
{
//Checks elided
var arr = new T[windowSize];
int r = windowSize - 1, i = 0;
using(var e = list.GetEnumerator())
{
while(e.MoveNext())
{
arr[i] = e.Current;
i = (i + 1) % windowSize;
if(r == 0)
yield return ArrayInit<T>(windowSize, j => arr[(i + j) % windowSize]);
else
r = r - 1;
}
}
}
public static T[] ArrayInit<T>(int size, Func<int, T> func)
{
var output = new T[size];
for(var i = 0; i < size; i++) output[i] = func(i);
return output;
}
'ArrayInit'への呼び出しを' var arrR = new T [windowSize];に置き換えます。 (int j = 0; j
'Seq.windowed'は' zeroCreateUnchecked'を使いますが、 'size'パラメータ(' size <0 then invalidArg ... ')の検証をスキップするだけです。境界チェックを回避しません。これはJITerの裁量で行なわれたものだと私は信じている。 – Daniel
@ダニエル、誰かが餌を取ってくれてうれしい:)私はあなたの結果を得ることができません。もし私が 'var list = Enumerable.Range(0、100000); var sw = Stopwatch.StartNew(); int count = list.Windowed(15).Count(); (新しい範囲で) 'Microsoft.FSharp.Collections.SeqModule.Windowed'で同じことをすると、C#は常に約2倍の時間がかかります... – Benjol
Reactive Extensionsは、BufferやWindowとしてこれを支援するためにいくつかの演算子を持っています。実験的なブランチにあるInteractive Extensionsは、これらと多くの追加演算子をLINQに追加します。
受け入れられた回答を提供したユーザーが間違っていたと認めた場合は、別のユーザーを選択することを検討することをおすすめします。 – Kev