有没有一种方法可以追加到列表并同时增加列表的大小?

时间:2019-04-09 03:35:18

标签: f#

我们需要生成8个随机数并将其放入列表中,然后测试它们是否为偶数。一次遍历列表,如果数字为偶数,则将“ Do”放入jobList,如果数字为奇数,则将“ Task”放入jobList。我们一直遇到列表每次重置的问题,然后当我们退出for循环时,jobList只是空的

let genRandomNumbers count =
    let rnd = System.Random()
    List.init count (fun _ -> rnd.Next(1,9))

let list = genRandomNumbers 8
printfn "Original: %A" list

let isEven x = (x % 2) = 0
let isOdd x = isEven x = false
let jobs = []
let jobList = []

for i in list do
  printfn "%A" i
  if(isEven i) then
    let jobList = List.append jobList ["Do"]
    printfn "%A" jobList
  else
    let jobList = List.append jobList ["Task"]
    printfn "%A" jobList

//printfn "%A" jobsList
//jobList = ["Do"]
//printfn "%A" jobList

2 个答案:

答案 0 :(得分:3)

F#列表是不可变的(又名ReadOnly),它在追加时会构造一个新列表。但是,可变结构是可用的。 ResizeArray将按照您的构造方式工作:

let genRandomNumbers count =
    let rnd = System.Random()
    List.init count (fun _ -> rnd.Next(1,9))

let list = genRandomNumbers 8

printfn "Original: %A" list

let isEven x = (x % 2) = 0

let isOdd x = isEven x = false

let jobs = []

let jobList = ResizeArray()


for i in list do
    printfn "%A" i
    if (isEven i) then
        jobList.AddRange(["Do"])
        printfn "%A" jobList
    else
        jobList.AddRange(["Task"])
        printfn "%A" jobList

但是,在F#中,“功能性和不可变的”编程风格是您正在使用F#而不是C#的功能。因此,使用带有Jarak's answer的map这样的高阶列表转换函数是理想的。

答案 1 :(得分:2)

您似乎有一个“重置”列表的原因是,使用显示的代码,您永远不会更新列表。每次第一次使用let x = y之后,您都在“影子” x(请参阅更多hereherehere),这意味着您声明一个名为x的新变量,直到新的x超出范围,才禁止访问旧的x

解决此问题的一种方法是使jobList可变(用let mutable jobList = []声明-进一步查看herehere),但是还有很多更好的方法。

如果我了解您想要的内容,本质上您想检查每个随机数,如果是偶数,则将“ Do”放入新列表中的该位置,但如果是奇数,则将“任务”。

最简单的方法是将List.map与执行该任务的函数一起使用。因此,您可以摆脱for循环,而改为使用以下内容:

let list = genRandomNumbers 8
printfn "Original: %A" list

let isEven x = (x % 2) = 0
let isOdd x = isEven x = false
let jobs = []

let evenDoOddTask i = 
    if (isEven i) then
        "Do"
    else
        "Task"

let jobList = List.map evenDoOddTask list

(我也强烈建议您不要将“ list”用作变量名,但我认为这只是出于示例的目的。)