我尝试修改 WikiBooks 示例以接受 csv 输入和类型,但正在努力将传入类型列表转换为字典并匹配用户输入。
// https://en.wikibooks.org/wiki/F_Sharp_Programming/Sets_and_Maps#Examples_2
module SOQN =
open System
open FSharp.Data
type Country = Country of string
type City = City of string
type CountryCapital = {
Country:Country
City:City
}
let [<Literal>] sampleCsv = @"D:\Country_Capitals.csv"
type Capitals = CsvProvider<sampleCsv, Separators=",", HasHeaders=true>
let readFromCsvFile (fileName:string) =
let data = Capitals.Load(fileName)
[ for row in data.Rows do
yield { Country = Country row.Country; City = City row.City; } ]
let countryCapitals =
readFromCsvFile sampleCsv
// -> |> Map.ofList
Console.Write("Find capital by country (type 'q' to quit): ")
match Console.ReadLine() with
| "q" -> Console.WriteLine("Bye!")
| country ->
match countryCapitals with
// -> | { Country = country } -> Console.WriteLine("Capital of {0} is {1}\n", country, capital)
| _ -> Console.WriteLine("Country not found.\n")
// Expected Output: Find capital by country (type 'q' to quit): Egypt
// Capital of Egypt is Cairo
我错过了什么?
最佳答案
您需要使用元组从List
创建Map
,因此您根本不需要记录类型。然后,您需要在输入国家/地区的 Map.tryFind
上进行匹配。以下是使用元组和 Map.tryFind 的示例。我所做的唯一其他更改是使用 printfn
而不是 Console.WriteLine
并简化列表生成表达式:
open System
open FSharp.Data
let [<Literal>] sampleCsv = @"D:\Country_Capitals.csv"
type Capitals = CsvProvider<sampleCsv, Separators=",", HasHeaders=true>
let readFromCsvFile (fileName:string) =
let data = Capitals.Load(fileName)
[ for row in data.Rows -> (row.Country, row.City) ]
let countryCapitals =
readFromCsvFile sampleCsv
|> Map.ofList
printfn "Find capital by country (type 'q' to quit): "
match Console.ReadLine() with
| "q" -> printfn "Bye!"
| country ->
match countryCapitals |> Map.tryFind country with
| Some capital -> printfn "Capital of %s is %s" country capital
| _ -> printfn "Country not found."
编辑要显示记录类型的持续使用:
open System
open FSharp.Data
type CountryCaptial = { Country: string; Capital: string }
let [<Literal>] sampleCsv = @"D:\Country_Capitals.csv"
type Capitals = CsvProvider<sampleCsv, Separators=",", HasHeaders=true>
let readFromCsvFile (fileName:string) =
let data = Capitals.Load(fileName)
[ for row in data.Rows -> { Country = row.Country; Capital = row.City } ]
let countryCapitals =
readFromCsvFile sampleCsv
|> List.map (fun c -> c.Country, c)
|> Map.ofList
printfn "Find capital by country (type 'q' to quit): "
match Console.ReadLine() with
| "q" -> printfn "Bye!"
| country ->
match countryCapitals |> Map.tryFind country with
| Some countryCapital -> printfn "Capital of %s is %s" countryCapital.Country countryCapital.Capital
| _ -> printfn "Country not found."
关于dictionary - F# 类型匹配 - 无法创建映射或匹配记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50394438/