这是一个很好的命令,它将与seq一起使用并生成任何大小的数组.如果序列不是n,则最后一个将更小.
let chunk n xs = seq { let i = ref 0 let arr = ref <| Array.create n (Unchecked.defaultof<'a>) for x in xs do if !i = n then yield !arr arr := Array.create n (Unchecked.defaultof<'a>) i := 0 (!arr).[!i] <- x i := !i + 1 if !i <> 0 then yield (!arr).[0..!i-1] }
我爱Seq.take
和Seq.skip
解决方案.它很漂亮,简单且易读,但我会使用这样的东西:
let chunks n (sequence: seq<_>) = let fold_fce (i, s) value = if i < n then (i+1, Seq.append s (Seq.singleton value)) else ( 1, Seq.singleton value) in sequence |> Seq.scan (fold_fce) (0, Seq.empty) |> Seq.filter (fun (i,_) -> i = n) |> Seq.map (Seq.to_array << snd )
它不是命令式代码,它应该比使用Seq.skip的解决方案更有效.另一方面,它将输入序列修剪为可被n整除的长度.如果这种行为是不可接受的,可以通过简单的修改来修复:
let chunks n (sequence: seq<_>) = let fold_fce (i, s) value = if i < n then (i+1, Seq.append s (Seq.singleton value)) else ( 1, Seq.singleton value) in sequence |> Seq.map (Some) |> fun s -> Seq.init_finite (n-1) (fun _ -> None) |> Seq.append s |> Seq.scan (fold_fce) (0, Seq.empty) |> Seq.filter (fun (i,_) -> i = n) |> Seq.map (Seq.to_array << (Seq.choose (id)) << snd )