F#: How do i split up a sequence into a sequence of sequences

后端 未结 8 2020
执念已碎
执念已碎 2021-01-02 06:12

Background:

I have a sequence of contiguous, time-stamped data. The data-sequence has gaps in it where the data is not contiguous. I want create a

8条回答
  •  一个人的身影
    2021-01-02 06:30

    (EDIT: This suffers from a similar problem to Brian's solution, in that iterating the outer sequence without iterating over each inner sequence will mess things up badly!)

    Here's a solution that nests sequence expressions. The imperitave nature of .NET's IEnumerable is pretty apparent here, which makes it a bit harder to write idiomatic F# code for this problem, but hopefully it's still clear what's going on.

    let groupBy cmp (sq:seq<_>) =
      let en = sq.GetEnumerator()
      let rec partitions (first:option<_>) =
        seq {
          match first with
          | Some first' ->             //'
            (* The following value is always overwritten; 
               it represents the first element of the next subsequence to output, if any *)
            let next = ref None
    
            (* This function generates a subsequence to output, 
               setting next appropriately as it goes *)
            let rec iter item = 
              seq {
                yield item
                if (en.MoveNext()) then
                  let curr = en.Current
                  if (cmp item curr) then
                    yield! iter curr
                  else // consumed one too many - pass it on as the start of the next sequence
                    next := Some curr
                else
                  next := None
              }
            yield iter first' (* ' generate the first sequence *)
            yield! partitions !next (* recursively generate all remaining sequences *)
          | None -> () // return an empty sequence if there are no more values
        }
      let first = if en.MoveNext() then Some en.Current else None
      partitions first
    
    let groupContiguousDataPoints (time:TimeSpan) : (seq -> _) = 
      groupBy (fun (t,_) (t',_) -> t' - t <= time)
    

提交回复
热议问题