バックグラウンド:
連続したタイムスタンプ付きのデータのシーケンスがあります。データ シーケンスには、データが連続していないギャップがあります。各サブシーケンスに連続したデータが含まれるように、シーケンスをシーケンスのシーケンスに分割するメソッドを作成したい (入力シーケンスをギャップで分割する)。
制約:
- 要素が必要に応じてのみ生成されるように、戻り値は一連のシーケンスでなければなりません(リスト/配列/キャッシュは使用できません)。
- 解は O(n^2) であってはならず、おそらく Seq.take - Seq.skip パターンを除外します ( Brian の投稿を参照) 。
- 関数型の慣用的なアプローチにはボーナス ポイントがありますが (関数型プログラミングに習熟したいので)、必須ではありません。
メソッド署名
let groupContiguousDataPoints (timeBetweenContiguousDataPoints : TimeSpan) (dataPointsWithHoles : seq<DateTime * float>) : (seq<seq< DateTime * float >>)= ...
一見問題は些細なことに見えましたが、Seq.pairwise、IEnumerator<_>、シーケンス内包表記、yield ステートメントを使用しても、解決策はわかりません。これは、F# イディオムを組み合わせた経験がまだないためか、まだ触れていない言語構造がいくつかあるためだと確信しています。
// Test data
let numbers = {1.0..1000.0}
let baseTime = DateTime.Now
let contiguousTimeStamps = seq { for n in numbers ->baseTime.AddMinutes(n)}
let dataWithOccationalHoles = Seq.zip contiguousTimeStamps numbers |> Seq.filter (fun (dateTime, num) -> num % 77.0 <> 0.0) // Has a gap in the data every 77 items
let timeBetweenContiguousValues = (new TimeSpan(0,1,0))
dataWithOccationalHoles |> groupContiguousDataPoints timeBetweenContiguousValues |> Seq.iteri (fun i sequence -> printfn "Group %d has %d data-points: Head: %f" i (Seq.length sequence) (snd(Seq.hd sequence)))