3 people like it.
Like the snippet!
Splitting a sequence based on separator condition
Whilst working on a google API wrapper, I came across the need to separate a sequence into sub-sequences based on a separator condition. This also led to a requirement for versions of takeWhile and skipWhile which also include the element which first breaks the condition predicate.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
|
let notEmpty s = not (Seq.isEmpty s)
// inclusive version of takeWhile - includes the element which broke the condition
let takeWhileInc cond s =
seq {
yield! s |> Seq.takeWhile cond
let r = s |> Seq.skipWhile cond
if notEmpty r then yield r |> Seq.head
}
// inclusive version of skipWhile - also skips the first element which broke the condition
let skipWhileInc cond s =
let r = s |> Seq.skipWhile cond
if notEmpty r then (r |> Seq.skip 1) else r
// split a large sequence into a sequence of sequences, determined by a splitter condition
let rec splitSubSequences cond s =
seq {
if not (s |> Seq.isEmpty) then
yield (s |> takeWhileInc cond)
yield! (s |> skipWhileInc cond |> splitSubSequences cond)
}
|
val notEmpty : s:seq<'a> -> bool
Full name: Script.notEmpty
val s : seq<'a>
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
module Seq
from Microsoft.FSharp.Collections
val isEmpty : source:seq<'T> -> bool
Full name: Microsoft.FSharp.Collections.Seq.isEmpty
val takeWhileInc : cond:('a -> bool) -> s:seq<'a> -> seq<'a>
Full name: Script.takeWhileInc
val cond : ('a -> bool)
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val takeWhile : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.takeWhile
val r : seq<'a>
val skipWhile : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.skipWhile
val head : source:seq<'T> -> 'T
Full name: Microsoft.FSharp.Collections.Seq.head
val skipWhileInc : cond:('a -> bool) -> s:seq<'a> -> seq<'a>
Full name: Script.skipWhileInc
val skip : count:int -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.skip
val splitSubSequences : cond:('a -> bool) -> s:seq<'a> -> seq<seq<'a>>
Full name: Script.splitSubSequences
More information