Я люблю 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 )