相当于Array.scan |> Array.skip 1,但是不创建中间数组?

rmu*_*unn 7 f#

Array.scan函数返回一个长度为 的数组n+1,其中n是其输入数组的长度,其第一项是传递给 的初始状态Array.scan。例如,

[|1;2;3;4|] |> Array.scan (+) 0  // Returns [|0;1;3;6;10|]
Run Code Online (Sandbox Code Playgroud)

但是,我通常发现这不是我想要的:我想要一个 length 数组n初始状态不会保留在我的输出数组中。我只需执行以下操作即可轻松获得此结果:

input |> Array.scan f initialState |> Array.skip 1
Run Code Online (Sandbox Code Playgroud)

但这将创建一个立即丢弃的中间数组。有没有一种好方法可以在不创建中间数组的情况下获得此结果?我可以很容易地自己实现:

let scanWithoutInitial f initState input =
    let result = Array.zeroCreate (Array.length input)
    let mutable state = initState
    for i = 0 to (Array.length input - 1) do
        state <- f state input.[i]
        result.[i] <- state
    result
Run Code Online (Sandbox Code Playgroud)

但是,重新实现我认为应该在标准 F# 核心库中的东西似乎需要做很多工作。有没有我忽略的功能?或者我是这个用例中唯一的一个,并且大多数人希望初始值作为他们Array.scan结果的第一项?

Fun*_*unk 4

mapFold正是这样做的:

Array.mapFold (fun acc x -> (acc + x, acc + x)) 0 [|1;2;3;4|] |> fst
Run Code Online (Sandbox Code Playgroud)

有关更多脑筋急转弯的信息,请参阅这篇文章