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).

Copy Source
Copy Link
Tools:

Implementation

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

Full name: Snippet.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>

  type: seq<'a>
  inherits: System.Collections.IEnumerable
Multiple items
val seq : 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<_>

  type: seq<'T>
  inherits: System.Collections.IEnumerable
val en : System.Collections.Generic.IEnumerator<'a>

  type: System.Collections.Generic.IEnumerator<'a>
  inherits: System.IDisposable
  inherits: System.Collections.IEnumerator
System.Collections.Generic.IEnumerable.GetEnumerator() : System.Collections.Generic.IEnumerator<'a>
val running : bool ref

  type: bool ref
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Ref<bool>>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
Multiple items
val ref : 'T -> 'T ref

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

--------------------

type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>

  type: 'T ref
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<Ref<'T>>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
val group : (unit -> 'a list)
property System.Collections.Generic.IEnumerator.Current: 'a
System.Collections.IEnumerator.MoveNext() : bool
val not : bool -> bool

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

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

from Snippet

--------------------

module Seq

from Microsoft.FSharp.Collections
val n : int

  type: int
  implements: System.IComparable
  implements: System.IFormattable
  implements: System.IConvertible
  implements: System.IComparable<int>
  implements: System.IEquatable<int>
  inherits: System.ValueType

More information

Link: http://fssnip.net/6A
Posted: 3 years ago
Author: Tomas Petricek (website)
Tags: sequences, seq, grouping, IEnumerator