シーケンスで列挙しつつ最後の要素かどうか判定する
リストの場合は再帰関数とパターンマッチングでできるんですが、シーケンスだとそうもいかず冗長になっちゃうなぁと思った。
リスト
[<Test>]
let ``detect last element of list`` () =
let rec loop = function
| [] -> ()
| [x] -> printfn "last %d" x
| h :: t -> printfn "%d" h ; loop t
let list = [ 1 .. 5 ]
loop list
シーケンス
[<Test>]
let ``detect last element of seq`` () =
let seq = seq { 1 .. 5 }
use e = seq.GetEnumerator()
(e, e.MoveNext())
|> Seq.unfold
(fun (e, hasCurrent) ->
if hasCurrent then
let current = e.Current
let hasNext = e.MoveNext()
Some ( (current, hasNext), (e, hasNext))
else
None)
|> Seq.iter
(fun (e, hasNext) ->
if hasNext then
printfn "%d" e
else
printfn "last %d" e)
出力結果
上のどちらのコードを動かしてもこういった結果になる。
1 2 3 4 last 5