Есть ли способ добавить в список и одновременно увеличить размер списка? - PullRequest
1 голос
/ 09 апреля 2019

Нам нужно сгенерировать 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 ]

3 голосов
/ 09 апреля 2019

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 #. Поэтому использование функции преобразования списка более высокого порядка, например map с ответом Jarak , является идеальным.

2 голосов
/ 09 апреля 2019

Причина, по которой у вас, похоже, есть список «сброса», заключается в том, что с указанным кодом вы никогда не обновляете список. Каждый раз, когда вы в первый раз используете let x = y, вы «затеняете» x (подробнее здесь , здесь и здесь ), что означает, что вы объявляете новую переменную с именем x и до тех пор, пока новая x не выйдет из области видимости, заблокировав доступ к старой x.

Один из способов исправить это состоит в том, чтобы сделать JobList изменяемым (объявите его с помощью let mutable jobList = [] - посмотрите здесь и здесь , чтобы узнать больше), но есть гораздо лучшие способы.

Если я понимаю, что вы хотите, по сути, вы хотите проверить каждое из случайных чисел и, если оно четное, поставить «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' в качестве имени переменной, но я предполагаю, что это только для примера).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...