1

We need to generate 8 random numbers and put them in a list, then test if they're even. The one at a time, going through the list, if the number is even then we put "Do" into jobList and if the number is odd then we put "Task" into jobList. We keep getting the issue where the list is resetting every time, then when we exit the for loop, jobList is just empty

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
3615
  • 3,787
  • 3
  • 20
  • 35
Jdosaj0606
  • 73
  • 1
  • 7

2 Answers2

3

F# List is immutable (aka ReadOnly) it constructs a new list when appending. However mutable structures are available. A ResizeArray would work the way you constructed this:

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

However, in F#, Functional & Immutable style of programming is kind of the feature you are using F# instead of C# for. So using a higher order list transformation function like map with Jarak's answer is ideal.

jbtule
  • 31,383
  • 12
  • 95
  • 128
2

The reason why you seem to have a 'reset' list is that, with the code shown, you are never updating the list. Every time after the first time you use let x = y, you are 'shadowing' x (see more here, here and here), meaning that you are declaring a new variable with the name x, and, until the new x goes out of scope, preventing access to the old x.

One way to fix this would be to make jobList mutable (declare it with let mutable jobList = [] - look here and here for more), but there are much better ways.

If I'm understanding what you want, essentially you want to check every one of the random numbers, and if it is even, put "Do" into that spot in a new list, but if it is odd, put "Task" in there.

The easiest way to do this would be to use List.map with a function that performs that task. So, you can get rid of the for loop, and use instead something along the lines of:

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

(I also would strongly advise against using 'list' as a variable name, but I'm assuming this is just for the sake of the example).

Jarak
  • 972
  • 9
  • 16