背景:
我有一系列连续的带时间戳的数据。数据序列中存在数据不连续的间隙。我想创建一种方法将序列拆分为一系列序列,以便每个子序列包含连续数据(在间隙处拆分输入序列)。
约束:
- 返回值必须是一个序列,以确保元素只根据需要产生(不能使用列表/数组/缓存)
- 解决方案不能是 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)))