1

我有一个calcArr_ArrOfArr用签名在 F# 中调用的函数int [] -> int [][] -> int,即calcArr_ArrOfArr接受两个参数,一个 int 数组和一个 int 数组数组,并返回一个 int。

我想创建calcArrOfArr带有签名的函数int [][] -> int,它执行以下操作:

let calcArrOfArr (arrOfArr : int [][]) =
    Array.fold (fun acc e -> acc + (calcArr_ArrOfArr e arrOfArr.[?..])) 0 arrOfArr

where?将是e+ 1的索引。
换句话说,calcArrOfArr我想应用于plus 的“剩余部分”的calcArr_ArrOfArr每个元素e,即从 after element 开始的切片。当然,对于 的最后一个元素,不会向累加器添加任何内容,也不会抛出异常。 有没有办法以功能方式创建?一个功能会派上用场...arrOfArrarrOfArrarrOfArrearrOfArr
calcArrOfArrArray.foldi

4

2 回答 2

4

如果你觉得你需要 Array.foldi,写一个!以下代码片段将使用折叠扩展内置 Array 模块:

module Array =
    let foldi f z a = 
        a |> Array.fold (fun (i,a) x -> i+1, f i a x) (0,z) |> snd

从过去切片为您提供空数组(即[|0;1|].[2..] = [||]),所以现在您的原始建议有效:

let calcArrOfArr (arrOfArr : int [][]) = 
    Array.foldi (fun i acc e -> acc + (calcArr_ArrOfArr e arrOfArr.[i+1..])) 0 arrOfArr 

但是,切片arrOfArr.[i+1..] 复制数组切片;这可能对效率不利。

于 2014-03-10T21:27:50.103 回答
3

没有测试过,但这似乎是正确的:

let calcArrOfArr (arrOfArr : int [][]) =
  arrOfArr
  |> Seq.mapi (fun i x -> i, x)
  |> Seq.fold (fun acc (i, e) -> acc + (calcArr_ArrOfArr e arrOfArr.[i+1..])) 0
于 2014-03-10T16:22:01.530 回答