如何在F#中使用可变列表?

时间:2017-10-17 20:26:32

标签: list f# mutable

我是F#的新手,我制作的程序需要找到某个列表中给定长度的每个子列表。我不确定如何解决这个问题所以我读了this question并决定将答案移到F#。这就是我所拥有的:

let rec getSubLists (len : int) (list : List<int>) : List<List<int>> =
  let result = new List<List<int>>()
  let current = new List<int>()

  let rec findSubLists (len : int) (superSet : List<int>) (current : List<int>) (soln : List<List<int>>) (idx : int) : unit =
    if current.Length = len then soln.Insert(len - 1, current)
    elif idx = superSet.Length then
      let x = superSet.[idx] 
      current.Insert(len, x)
      findSubLists len superSet current soln (idx + 1)
      current.RemoveAt(x)
      findSubLists len superSet current soln (idx + 1)
    else ()

  findSubLists len list current result 0
  result

编译器对一些事情感到不安:它说List<int>List<List<int>>没有构造函数,并且它表示没有定义InsertRemoveAt。我在microsoft docs中找到了这些方法。 This tutorial提及RemoveAt,但它使用Add代替Insert,而 Error: Module version mismatch. Expected 48, got 51. at Error (native) at Object.Module._extensions..node (module.js:597:18) 也无效。

1 个答案:

答案 0 :(得分:5)

在F#中,类型List<'t>是不可变的F#列表。它与System.Collections.Generic.List<T>不同,后者是您链接的文档中描述的内容。

要访问后者,请打开System.Collections.Generic命名空间(但要注意:这会影响常规F#列表)或通过其F#别名ResizeArray<'t>引用它,这也更好地表达了它的真实性性质。

let rec getSubLists (len : int) (list : ResizeArray<int>) : ResizeArray<ResizeArray<int>> =
  let result = new ResizeArray<ResizeArray<int>>()
  let current = new ResizeArray<int>()

  let rec findSubLists (len : int) (superSet : ResizeArray<int>) (current : ResizeArray<int>) (soln : ResizeArray<ResizeArray<int>>) (idx : int) : unit =
    if current.Count = len then soln.Insert(len - 1, current)
    elif idx = superSet.Count then
      let x = superSet.[idx] 
      current.Insert(len, x)
      findSubLists len superSet current soln (idx + 1)
      current.RemoveAt(x)
      findSubLists len superSet current soln (idx + 1)
    else ()

  findSubLists len list current result 0
  result

(还要注意它的Count,而不是Length