0 people like it.

Break a sequence on a predicate

Break a sequence into sub-sequences, where the break occurs at points where the specified function returns true when provided with the n'th and the n+1'th elements of the input sequence.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
module Seq 

/// Break a sequence into sub-sequences, where the break occurs at points
/// where the specified function returns true when provided with the n'th
/// and the n+1'th elements of the input sequence.
let BreakOn (f : 'a -> 'a -> bool) (s : seq<'a>) =
    if s |> Seq.isEmpty then
        Seq.empty
    else
        let len = s |> Seq.length
        let last = s |> Seq.nth (len-1)
        let pairs = s |> Seq.pairwise |> Seq.map (fun (x, y) -> x, Some(y))
        let pairs' = Seq.append pairs [last, None]
        seq {
            let acc = ref(Seq.empty)
            for x, y in pairs' do
                if (y.IsSome && (f x y.Value))
                   || y.IsNone then
                    yield (Seq.append !acc [x])
                    acc := Seq.empty
                else
                    acc := Seq.append !acc [x]
        }

// Examples:

let FilesByExt() = 
    System.IO.Directory.EnumerateFiles(@"d:\temp\")
    |> Seq.sortBy (fun name -> System.IO.Path.GetExtension(name.ToUpper()))
    |> BreakOn (fun name1 name2 -> System.IO.Path.GetExtension(name1.ToUpper()) <> System.IO.Path.GetExtension(name2.ToUpper()))
    |> Seq.iter (fun group -> group |> Seq.iter (fun name -> printfn "%s" name); printfn "---------------------------")
// d:\temp\expmvc.bak
// d:\temp\EXPMVC_ICI.BAK
// d:\temp\EXPMVC_ICI_BBC.BAK
// ---------------------------
// d:\temp\file.csv
// ---------------------------
// d:\temp\1m.txt.dedupe
// d:\temp\29m.txt.dedupe
// d:\temp\29mx4.txt.dedupe
// ---------------------------
// d:\temp\stainedglasslatinsquare.html
// d:\temp\window2.html
// ---------------------------

let Paginate() =
    [1..200] |> BreakOn (fun page _ -> page % 60 = 0)
// > Paginate();;
// val it : seq<seq<int>> =
//   seq
//     [seq [1; 2; 3; 4; ...]; 
//      seq [61; 62; 63; 64; ...];
//      seq [121; 122; 123; 124; ...]; 
//      seq [181; 182; 183; 184; ...]]

// See http://fssnip.net/fe
let Conway (seed : string) =
    seed
    |> BreakOn (fun c1 c2 -> c1 <> c2)
    |> Seq.map (fun grp -> let count, character = grp |> Seq.length, grp |> Seq.nth 0
                           count.ToString() + character.ToString() )
    |> Seq.concat
    |> Seq.fold (fun acc elem -> sprintf "%s%c" acc elem) ""
// > Conway "1211";;
// val it : string = "111221"

let ConwaySeq (first : string) =
    Seq.unfold (fun seed -> Some(seed, Conway seed)) first
// > ConwaySeq "1" |> Seq.take 5 |> List.ofSeq;;
// val it : string list = ["1"; "11"; "21"; "1211"; "111221"]
Multiple items
module Seq

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

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

Full name: Seq.BreakOn


 Break a sequence into sub-sequences, where the break occurs at points
 where the specified function returns true when provided with the n'th
 and the n+1'th elements of the input sequence.
val f : ('a -> 'a -> bool)
type bool = System.Boolean

Full name: Microsoft.FSharp.Core.bool
val s : 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<_>
module Seq

from Microsoft.FSharp.Collections
val isEmpty : source:seq<'T> -> bool

Full name: Microsoft.FSharp.Collections.Seq.isEmpty
val empty<'T> : seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.empty
val len : int
val length : source:seq<'T> -> int

Full name: Microsoft.FSharp.Collections.Seq.length
val last : 'a
val nth : index:int -> source:seq<'T> -> 'T

Full name: Microsoft.FSharp.Collections.Seq.nth
val pairs : seq<'a * 'a option>
val pairwise : source:seq<'T> -> seq<'T * 'T>

Full name: Microsoft.FSharp.Collections.Seq.pairwise
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val x : 'a
val y : 'a
union case Option.Some: Value: 'T -> Option<'T>
val pairs' : seq<'a * 'a option>
val append : source1:seq<'T> -> source2:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.append
union case Option.None: Option<'T>
val acc : seq<'a> 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 y : 'a option
property Option.IsSome: bool
property Option.Value: 'a
property Option.IsNone: bool
val FilesByExt : unit -> unit

Full name: Seq.FilesByExt
namespace System
namespace System.IO
type Directory =
  static member CreateDirectory : path:string -> DirectoryInfo + 1 overload
  static member Delete : path:string -> unit + 1 overload
  static member EnumerateDirectories : path:string -> IEnumerable<string> + 2 overloads
  static member EnumerateFileSystemEntries : path:string -> IEnumerable<string> + 2 overloads
  static member EnumerateFiles : path:string -> IEnumerable<string> + 2 overloads
  static member Exists : path:string -> bool
  static member GetAccessControl : path:string -> DirectorySecurity + 1 overload
  static member GetCreationTime : path:string -> DateTime
  static member GetCreationTimeUtc : path:string -> DateTime
  static member GetCurrentDirectory : unit -> string
  ...

Full name: System.IO.Directory
System.IO.Directory.EnumerateFiles(path: string) : System.Collections.Generic.IEnumerable<string>
System.IO.Directory.EnumerateFiles(path: string, searchPattern: string) : System.Collections.Generic.IEnumerable<string>
System.IO.Directory.EnumerateFiles(path: string, searchPattern: string, searchOption: System.IO.SearchOption) : System.Collections.Generic.IEnumerable<string>
val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Seq.sortBy
val name : string
type Path =
  static val DirectorySeparatorChar : char
  static val AltDirectorySeparatorChar : char
  static val VolumeSeparatorChar : char
  static val InvalidPathChars : char[]
  static val PathSeparator : char
  static member ChangeExtension : path:string * extension:string -> string
  static member Combine : [<ParamArray>] paths:string[] -> string + 3 overloads
  static member GetDirectoryName : path:string -> string
  static member GetExtension : path:string -> string
  static member GetFileName : path:string -> string
  ...

Full name: System.IO.Path
System.IO.Path.GetExtension(path: string) : string
System.String.ToUpper() : string
System.String.ToUpper(culture: System.Globalization.CultureInfo) : string
val name1 : string
val name2 : string
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val group : seq<string>
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val Paginate : unit -> seq<seq<int>>

Full name: Seq.Paginate
val page : int
val Conway : seed:string -> string

Full name: Seq.Conway
val seed : string
Multiple items
val string : value:'T -> string

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

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val c1 : char
val c2 : char
val grp : seq<char>
val count : int
val character : char
System.Int32.ToString() : string
System.Int32.ToString(provider: System.IFormatProvider) : string
System.Int32.ToString(format: string) : string
System.Int32.ToString(format: string, provider: System.IFormatProvider) : string
System.Char.ToString() : string
System.Char.ToString(provider: System.IFormatProvider) : string
val concat : sources:seq<#seq<'T>> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.concat
val fold : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State

Full name: Microsoft.FSharp.Collections.Seq.fold
val acc : string
val elem : char
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val ConwaySeq : first:string -> seq<string>

Full name: Seq.ConwaySeq
val first : string
val unfold : generator:('State -> ('T * 'State) option) -> state:'State -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.unfold
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/fg
Posted:12 years ago
Author:Kit Eason
Tags: sequences