2 people like it.

Seq.groupWhen function

The snippet declares a function that groups adjacent elements of a sequence. A new group is started when the specified predicate holds about an element. Groups are constructed eagerly (using lists).

Implementation

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
module Seq =
  /// Iterates over elements of the input sequence and groups adjacent elements.
  /// A new group is started when the specified predicate holds about the element
  /// of the sequence (and at the beginning of the iteration).
  ///
  /// For example: 
  ///    Seq.groupWhen isOdd [3;3;2;4;1;2] = seq [[3]; [3; 2; 4]; [1; 2]]
  let groupWhen f (input:seq<_>) = seq {
    use en = input.GetEnumerator()
    let running = ref true
    
    // Generate a group starting with the current element. Stops generating
    // when it founds element such that 'f en.Current' is 'true'
    let rec group() = 
      [ yield en.Current
        if en.MoveNext() then
          if not (f en.Current) then yield! group() 
        else running := false ]
    
    if en.MoveNext() then
      // While there are still elements, start a new group
      while running.Value do
        yield group() |> Seq.ofList }

Example

1: 
[3;3;2;4;1;2] |> Seq.groupWhen (fun n -> n%2 = 1)
module Seq

from Microsoft.FSharp.Collections
val groupWhen : f:('a -> bool) -> input:seq<'a> -> seq<seq<'a>>

Full name: Script.Seq.groupWhen


 Iterates over elements of the input sequence and groups adjacent elements.
 A new group is started when the specified predicate holds about the element
 of the sequence (and at the beginning of the iteration).

 For example:
    Seq.groupWhen isOdd [3;3;2;4;1;2] = seq [[3]; [3; 2; 4]; [1; 2]]
val f : ('a -> bool)
val input : seq<'a>
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 en : System.Collections.Generic.IEnumerator<'a>
System.Collections.Generic.IEnumerable.GetEnumerator() : System.Collections.Generic.IEnumerator<'a>
val running : bool ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val group : (unit -> 'a list)
property System.Collections.Generic.IEnumerator.Current: 'a
System.Collections.IEnumerator.MoveNext() : bool
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
property Ref.Value: bool
val ofList : source:'T list -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.ofList
Multiple items
module Seq

from Script

--------------------
module Seq

from Microsoft.FSharp.Collections
val n : int

More information

Link:http://fssnip.net/6A
Posted:7 years ago
Author:Tomas Petricek
Tags: sequences , seq , grouping , ienumerator