序列的F#array_chunk

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)

Mic*_*lGG 5

这是一个很好的命令,它将与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.takeSeq.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)


Ray*_*Ray 5

这个答案可能会被掩盖,但这是我对这个问题的看法:

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)

优点:

  • 仅使用 seq,不使用数组
  • O(n) 运行时。不像 Seq.skip/take 解决方案那样 O(n^2)
  • Seq.length 不必是 n 的倍数
  • 小而易懂?

缺点:

  • 可能不如命令式/可变循环有效