首页 > 解决方案 > 在这种情况下是否可以使用不可变集合?

问题描述

我已将代码从 python 翻译成 F#,但我希望使用更惯用的语法。我认为有两大障碍

我拥有的当前(工作)代码是

let valuefolded =
    System.Collections.Generic.List(
        [0..( (n - (offset % input.Length) - 1) / input.Length)]
        |> List.fold
            (fun acc _ -> List.append acc input)
            (input
            |> List.skip (offset % input.Length)))
for repeat in [0..99] do  
    let mutable acc = 0
    for i in ([0..(n-1)] |> List.rev) do
        valuefolded.[i] <- Math.Abs(acc + valuefolded.[i]) % 10
        acc <- valuefolded.[i]

(在我的笔记本电脑上使用实际数据,大约需要一分钟)

现在有两个可变的,我希望使不可变,如果它是可能的,如果它是有意义的。

  1. mutable acc完成,见下文)
  2. System.Collections.Generic.List包装器

标签: f#immutabilityimmutable-collections

解决方案


看起来您Generic.List仅用于拥有可以通过索引访问的集合。您可以改用内置数组。这是代码

let valuefolded =        
        [0..( (n - (offset % input.Length) - 1) / input.Length)]
        |> List.fold
            (fun acc _ -> List.append acc input)
            (input
            |> List.skip (offset % input.Length))
        |> Array.ofList

另外,我鼓励您自己检查,但我对以下参数的观察

let offset = 1
    let input = [1..10000000]
    let n = 3

表明它比原始版本执行得更快。


推荐阅读