在 F# 中使用 array.fold 的累积和
cumulative sum using array.fold in F#
我有一个以下类型的数组
let myarray = [| 1 .. 5 |]
我想得到另一个数组,其中每个元素都是它之前的元素的累加和:
let mycumarray = [| 1 3 6.. 15 |]
我尝试做的是:
let sumArray array = Array.fold (fun acc elem -> acc + elem) 0.0 array
let mycumarray = sumArray myarray
然而它不起作用。有人对获得累计金额有什么建议吗?
我认为您正在寻找 Array.scan
,这与 Array.fold
非常相似,但是 returns 所有状态值而不仅仅是最后一个:
(Array.scan (+) 0 myArray).[1..]
.[1..]
是数组切片器表示法 (see the MSDN on arrays in F#),用于删除第一个元素,这是必需的,因为 scan
在输出中包含初始状态。
Array.scan
无疑是最好的解决方案,但如果您愿意,可以使用 fold
:
let cumList xs =
List.ofSeq xs
|> List.fold (fun (acc, ys) elem ->
let acc' = acc + elem
in (acc', ys @ [acc']))
(0, [])
|> snd
|> List.toArray
这是你的例子:
> cumList [|1..5|];;
val it : int [] = [|1; 3; 6; 10; 15|]
请注意,@
不是最优的,但它很好地显示了已完成的工作(如果性能很重要,您可以使用 List.foldBack
或在其中执行 ::
,最后 List.rev
以获得正确的顺序。
您也可以直接使用 Array.append
而不是 @
使示例在数字上通用:
let inline cumList xs =
List.ofSeq xs
|> List.fold (fun (acc, ys) elem ->
let acc' = acc + elem
in (acc', ys @ [acc']))
(LanguagePrimitives.GenericZero, [])
|> snd
|> List.toArray
你看你只需要创建函数 inline
并使用 GenericZero
而不是 0
(假定为 int
)
顺便说一句:这也适用于 Array.scan
方法:
let inline cumList2 xs =
Array.scan (+) LanguagePrimitives.GenericOne xs
备注 如果您只是从 1
而不是 0
!
开始,则在这种情况下不需要数组切片
我有一个以下类型的数组
let myarray = [| 1 .. 5 |]
我想得到另一个数组,其中每个元素都是它之前的元素的累加和:
let mycumarray = [| 1 3 6.. 15 |]
我尝试做的是:
let sumArray array = Array.fold (fun acc elem -> acc + elem) 0.0 array
let mycumarray = sumArray myarray
然而它不起作用。有人对获得累计金额有什么建议吗?
我认为您正在寻找 Array.scan
,这与 Array.fold
非常相似,但是 returns 所有状态值而不仅仅是最后一个:
(Array.scan (+) 0 myArray).[1..]
.[1..]
是数组切片器表示法 (see the MSDN on arrays in F#),用于删除第一个元素,这是必需的,因为 scan
在输出中包含初始状态。
Array.scan
无疑是最好的解决方案,但如果您愿意,可以使用 fold
:
let cumList xs =
List.ofSeq xs
|> List.fold (fun (acc, ys) elem ->
let acc' = acc + elem
in (acc', ys @ [acc']))
(0, [])
|> snd
|> List.toArray
这是你的例子:
> cumList [|1..5|];;
val it : int [] = [|1; 3; 6; 10; 15|]
请注意,@
不是最优的,但它很好地显示了已完成的工作(如果性能很重要,您可以使用 List.foldBack
或在其中执行 ::
,最后 List.rev
以获得正确的顺序。
您也可以直接使用 Array.append
而不是 @
使示例在数字上通用:
let inline cumList xs =
List.ofSeq xs
|> List.fold (fun (acc, ys) elem ->
let acc' = acc + elem
in (acc', ys @ [acc']))
(LanguagePrimitives.GenericZero, [])
|> snd
|> List.toArray
你看你只需要创建函数 inline
并使用 GenericZero
而不是 0
(假定为 int
)
顺便说一句:这也适用于 Array.scan
方法:
let inline cumList2 xs =
Array.scan (+) LanguagePrimitives.GenericOne xs
备注 如果您只是从 1
而不是 0
!