13 people like it.
Like the snippet!
Chronological sequence window beginnings
An abstraction of the following use case:
Given a sequence of dates and max temperatures for each date, extract out the initial dates on which the temp is greater than a given threshold for n consecutive days.
(Originally posted as an answer to this StackOverflow question: http://stackoverflow.com/questions/5267055 )
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
|
let findWindowBeginnings predicate minWindowSize data =
if minWindowSize < 2 then invalidArg "minWindowSize" "minWindowSize must be greater than 1"
((None, []), data)
||> Seq.fold (fun (window, acc) x ->
if predicate x then
match window with
| Some (start, size) -> let size' = size + 1
let acc' = if size' = minWindowSize then start::acc else acc
Some (start, size'), acc'
| _ -> Some (x, 1), acc
else None, acc)
|> snd
|> List.rev
// example usage, implementing described use case:
let findHeatwaveBeginnings tempThreshold consecutiveDays data =
(consecutiveDays, data)
||> findWindowBeginnings (snd >> (<=) tempThreshold)
// alternatively, if one isn't a fan of point-free style code:
// findWindowBeginnings (fun (_, maxTemp) -> maxTemp > tempThreshold)
|> List.map fst
|
val findWindowBeginnings : predicate:('a -> bool) -> minWindowSize:int -> data:seq<'a> -> 'a list
Full name: Script.findWindowBeginnings
val predicate : ('a -> bool)
val minWindowSize : int
val data : seq<'a>
val invalidArg : argumentName:string -> message:string -> 'T
Full name: Microsoft.FSharp.Core.Operators.invalidArg
union case Option.None: Option<'T>
module Seq
from Microsoft.FSharp.Collections
val fold : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State
Full name: Microsoft.FSharp.Collections.Seq.fold
val window : ('a * int) option
val acc : 'a list
val x : 'a
union case Option.Some: Value: 'T -> Option<'T>
val start : 'a
val size : int
val size' : int
val acc' : 'a list
val snd : tuple:('T1 * 'T2) -> 'T2
Full name: Microsoft.FSharp.Core.Operators.snd
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val rev : list:'T list -> 'T list
Full name: Microsoft.FSharp.Collections.List.rev
val findHeatwaveBeginnings : tempThreshold:'a -> consecutiveDays:int -> data:seq<'b * 'a> -> 'b list (requires comparison)
Full name: Script.findHeatwaveBeginnings
val tempThreshold : 'a (requires comparison)
val consecutiveDays : int
val data : seq<'b * 'a> (requires comparison)
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.map
val fst : tuple:('T1 * 'T2) -> 'T1
Full name: Microsoft.FSharp.Core.Operators.fst
More information