Создайте список пользовательских типов в F # и создайте две последовательности этого списка - PullRequest
0 голосов
/ 22 апреля 2020

Я создал свой собственный тип в F # под названием Учетные записи, а затем я создал объекты для каждой учетной записи.

type Account() =   

  let AccountNumber = ""
  let mutable Balance:float = 0.0

Каждая учетная запись имеет два поля: AccountNumber (строка) и Balance (плавающее).

Затем я создал объект для каждой учетной записи, которая содержит имя учетной записи и баланс.

let acc1 = new Account()  
acc1.Insert("John",10.0)

let acc2 = new Account()  
acc2.Insert("Mike",50.0)

Как мне создать список, содержащий каждую учетную запись (объект)? Я пробовал следующее:

let AccountList : Account list = [acc1;  acc2 ;  acc3; acc4 ; acc5; acc6]
let AccountList : Account obj list = [acc1;  acc2 ;  acc3; acc4 ; acc5; acc6]

Я не могу решить проблему, используя вышеупомянутый метод, потому что мне нужно создать две последовательности из списка:

Последовательность 1: Все счета с большим балансом или равно нулю и меньше 50 Последовательность 2: Все учетные записи с балансом выше 50

Как мне создать список моего пользовательского типа в F # и как мне создать две последовательности этого списка?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Не ясно, с чем именно вы боретесь. Однако следующий простой пример должен иллюстрировать большинство ключевых идей, которые вам, вероятно, нужно использовать. Во-первых, вот небольшая версия вашего Account класса (обратите внимание, что я обычно использовал бы неизменную запись, но я сохранил ее так, как вы это сделали):

type Account(balance:float) =   
  let mutable balance = balance
  member x.Balance = balance
  member x.Add(difference) = 
    balance <- balance + difference

Я не вижу, в чем проблема у вас есть с созданием списка. Следующее прекрасно работает:

let acc1 = Account(100.0)
let acc2 = Account(10.0)

let accountList = [acc1; acc2]

Теперь, чтобы ответить на вопрос о поиске счетов с балансом более 50, вы можете использовать функцию List.filter для создания нового отфильтрованного списка:

let above50 = 
  accountList |> List.filter (fun acc ->
    acc.Balance > 50.0)

РЕДАКТИРОВАТЬ Если вы хотите использовать вместо этого запись, вы должны определить тип как:

type Account = { Balance : float }

И создать значение, используя:

let acc1 = { Balance = 100.0 }
0 голосов
/ 23 апреля 2020

Итак, я создал этот ответ для другого, но я ждал комментария, чтобы посмотреть, отвечу ли я. И домашнее задание, похожее на это:)

Так что, если у вас есть критерии, которые включают учетную запись, и вы хотите сделать это за один проход, вы можете посмотреть на groupBy. Здесь я использую boolean, потому что есть только 2 варианта, но числа или дискриминированный союз являются хорошими кандидатами.

open System

type Account(accountNumber:string, startingBalance:Int64) =
    let mutable balance = startingBalance

    member _.Balance = balance
    member _.Deposit amount = balance <- balance + amount
    member _.Withdraw amount = balance <- balance - amount
    override _.ToString() = accountNumber

let allAccounts = [Account("ABC1", 10L); Account("ABC2", 50L)]

let grouped = allAccounts |> List.groupBy (fun a -> a.Balance >= 50L) |> Map.ofList

let under50 = grouped |> Map.tryFind false |> Option.defaultValue []
let overIncl50 = grouped |> Map.tryFind true |> Option.defaultValue []

printfn "Under: %A" under50
printfn "Over: %A" overIncl50
...