gra*_*bot 6 arrays f# sequence chunking
我在制作序列时遇到了一些麻烦.基本上我需要将序列切割成一系列数组.Seq.windowed几乎做到了,但我不想要重复的元素.
我可以通过首先将所有内容读入数组来获得我想要的内容,但我宁愿使用序列.
let array_chunk s (a:int[]) =
Array.init (a.Length / s) (fun i -> Array.sub a (i * s) s)
someSequence |> Seq.to_array |> array_chunk 5
Run Code Online (Sandbox Code Playgroud)
这是一个很好的命令,它将与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] }
Run Code Online (Sandbox Code Playgroud)
小智 5
我爱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 )
Run Code Online (Sandbox Code Playgroud)
它不是命令式代码,它应该比使用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 )
Run Code Online (Sandbox Code Playgroud)
这个答案可能会被掩盖,但这是我对这个问题的看法:
let chunk n xs =
xs
|> Seq.mapi(fun i x -> i/n, x)
|> Seq.groupBy fst
|> Seq.map (fun (_, g) -> Seq.map snd g)
Run Code Online (Sandbox Code Playgroud)
优点:
缺点: