Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split seq in F#

Tags:

split

f#

seq

I should split seq<a> into seq<seq<a>> by an attribute of the elements. If this attribute equals by a given value it must be 'splitted' at that point. How can I do that in FSharp?

It should be nice to pass a 'function' to it that returns a bool if must be splitted at that item or no.

Sample: Input sequence: seq: {1,2,3,4,1,5,6,7,1,9} It should be splitted at every items when it equals 1, so the result should be:

seq
{
seq{1,2,3,4}
seq{1,5,6,7}
seq{1,9}
}
like image 993
Tom Avatar asked Jul 18 '11 16:07

Tom


1 Answers

All you're really doing is grouping--creating a new group each time a value is encountered.

let splitBy f input =
  let i = ref 0
  input 
  |> Seq.map  (fun x -> 
    if f x then incr i
    !i, x)
  |> Seq.groupBy fst
  |> Seq.map (fun (_, b) -> Seq.map snd b)

Example

let items = seq [1;2;3;4;1;5;6;7;1;9]
items |> splitBy ((=) 1)

Again, shorter, with Stephen's nice improvements:

let splitBy f input =
  let i = ref 0
  input
  |> Seq.groupBy (fun x ->
    if f x then incr i
    !i)
  |> Seq.map snd
like image 126
Daniel Avatar answered Oct 02 '22 20:10

Daniel