p_tan's blog

勉強日記です。ツッコミ大歓迎

シーケンスの前後の値を見ながらの処理 Seq.windowed [追記] #fsharp

  • Seq.windowedはseq中の隣接するn要素の配列のseqを返す関数。
> Seq.windowed 3 [1..5];;
val it : seq<int []> = seq [[|1; 2; 3|]; [|2; 3; 4|]; [|3; 4; 5|]]
  • 例えば数値のシーケンスの極大値のみをselectする処理は以下のように書ける。
> let SelectLocalMaxs (sq : 'a seq) = 
    sq
    |> Seq.windowed 3
    |> Seq.filter (fun x -> x.[0] < x.[1] && x.[1] > x.[2])
    |> Seq.map (fun x -> x.[1]);;

val SelectLocalMaxs : seq<'a> -> seq<'a> when 'a : comparison

> SelectLocalMaxs [0;1;0;-1;0;-1];;
val it : seq<int> = seq [1; 0]
  • Seq.chooseを使っても良い
let SelectLocalMaxs (sq : 'a seq) =
    sq
    |> Seq.windowed 3
    |> Seq.choose (fun x -> if (x.[0] < x.[1] && x.[1] > x.[2]) then Some x.[1] else None)

追記

「実践F#」の著者の一人である@さんからご指摘をいただきました。


実践 F# 関数型プログラミング入門


twitter:63414623201804289:tree

というわけで、配列のパターンマッチを使えばよりスマートで安全なコードが書けます。