for i in a..b do
res <- res * myarray.[i]
res
我必须像这样使用吗
Array.fold (*) 1 (Array.sub myarray a (b - a + 1))
,我认为这相当慢而且不是那么简洁?
for i in a..b do
res <- res * myarray.[i]
res
我必须像这样使用吗
Array.fold (*) 1 (Array.sub myarray a (b - a + 1))
,我认为这相当慢而且不是那么简洁?
不知道你是否会发现它更好,但你可以这样做:
Seq.fold (fun r i -> r * myarray.[i]) 1 {a .. b}
Daniel 的解决方案非常简洁,我认为它应该几乎与for
循环一样有效,因为它不需要克隆数组。
如果您想要一个更简洁的解决方案,那么您可以使用 indexer 而不是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
我相信这更直接地表达了您尝试实现的功能。与性能一样 - 您应该测量性能以查看是否需要进行此类优化,或者第一个版本是否足够快以满足您的目的。
如果您关心速度,那么我会回避使用 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
这里没有开销,它尽可能快,没有突变,它是功能性的。