我们需要生成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
答案 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
(请参阅更多here,here和here),这意味着您声明一个名为x
的新变量,直到新的x
超出范围,才禁止访问旧的x
。
解决此问题的一种方法是使jobList可变(用let mutable jobList = []
声明-进一步查看here和here),但是还有很多更好的方法。
如果我了解您想要的内容,本质上您想检查每个随机数,如果是偶数,则将“ 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”用作变量名,但我认为这只是出于示例的目的。)