问题
I have created my own type in F# called Accounts and I have then created objects for each account.
type Account() =
let AccountNumber = ""
let mutable Balance:float = 0.0
Every account has two fields, AccountNumber (string) and Balance (float).
I have then created an object for every account that holds the AccountName and the Balance.
let acc1 = new Account()
acc1.Insert("John",10.0)
let acc2 = new Account()
acc2.Insert("Mike",50.0)
How do I create a list that holds each account (object)? I have tried the following:
let AccountList : Account list = [acc1; acc2 ; acc3; acc4 ; acc5; acc6]
let AccountList : Account obj list = [acc1; acc2 ; acc3; acc4 ; acc5; acc6]
I cannot solve the problem using the above method because I have to create two sequences from the list:
Sequence 1: All accounts with a balance greater or equal to zero and less than 50 Sequence 2: All accounts with a balance above 50
How do I create a list of my custom type in F# and how do I create two sequences of that list?
回答1:
It is not clear what exactly are you struggling with. However, the following simple example should illustrate most of the key ideas that you probably need to use. First, here is a small version of your Account
class (note that I would normally use an immutable record, but I kept it the way you did it):
type Account(balance:float) =
let mutable balance = balance
member x.Balance = balance
member x.Add(difference) =
balance <- balance + difference
I do not see what issue you have with creating the list. The following works just fine:
let acc1 = Account(100.0)
let acc2 = Account(10.0)
let accountList = [acc1; acc2]
Now, to answer the question about finding accounts with balance over 50, you can use the List.filter
function to create a new filtered list:
let above50 =
accountList |> List.filter (fun acc ->
acc.Balance > 50.0)
EDIT If you wanted to use a record instead, then you would define the type as:
type Account = { Balance : float }
And create a value using:
let acc1 = { Balance = 100.0 }
回答2:
So I created this answer for the other one but I was waiting on the comment to see if I would answer. And the homework like aspect of this :)
So if you have criteria that bucket an account and want to do that in a single pass, you might want to look at groupBy
. Here I use a boolean
because there are only 2 possibilities but numbers or a discriminated union are good candidates.
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
来源:https://stackoverflow.com/questions/61368307/create-a-list-of-custom-type-in-f-and-create-two-sequences-of-that-list