for i in a..b do
res <- res * myarray.[i]
res
我必须使用
Array.fold (*) 1 (Array.sub myarray a (b - a + 1))
,我认为这是相当缓慢而不是那么简洁?
答案 0 :(得分:5)
不知道你是否会更好地找到它,但你可以这样做:
Seq.fold (fun r i -> r * myarray.[i]) 1 {a .. b}
答案 1 :(得分:4)
Daniel的解决方案非常简洁,我认为它应该与for
循环一样高效,因为它不需要克隆数组。
如果你想要一个更简洁的解决方案,那么你可以使用索引器而不是Array.sub
,它需要克隆数组的某些部分,但它看起来非常整洁:
myarray.[a .. b] |> Seq.fold (*) 1
这会克隆数组的一部分,因为切片操作会返回一个数组。您可以定义自己的切片操作,将元素返回为seq<'T>
(因此不会克隆整个数组):
module Array =
let slice a b (arr:'T[]) =
seq { for i in a .. b -> arr.[i] }
使用此功能,您可以写:
myarray |> Array.slice a b |> Seq.fold (*) 1
我相信这更直接地表达了您尝试实现的功能。与性能一样 - 您应该测量性能以确定是否需要进行此类优化,或者第一个版本是否足够快以达到您的目的。
答案 2 :(得分:4)
如果你关注速度,那么除非你是原型,否则我会回避使用seq。要么坚持使用for循环,要么重写为递归函数。您给出的示例是简单的,有时更复杂的问题更好地表示为递归。
let rec rangeProduct a b total (array : _[]) =
if a <= b then
rangeProduct (a + 1) b (total * array.[a]) array
else
total
let res = myArray |> rangeProduct a b res
这里没有开销,它尽可能快,没有突变,而且功能正常。