给出一个字符串,如
一个:1.0 | 2:2.0 | 3:3.0
我们如何创建表单字符串的字典:float?
open System
open System.Collections.Generic
let ofSeq (src:seq<'a * 'b>) =
// from fssnip
let d = new Dictionary<'a, 'b>()
for (k,v) in src do
d.Add(k,v)
d
let msg = "one:1.0|two:2.0|three:3.0"
let msgseq = msg.Split[|'|'|] |> Array.toSeq |> Seq.map (fun i -> i.Split(':'))
let d = ofSeq msgseq // The type ''a * 'b' does not match the type 'string []'
此操作将在一个紧凑的循环中,因此效率将是一个加号。虽然我想看到一个简单的解决方案,只是为了获得我的F#轴承。
感谢。
答案 0 :(得分:3)
这样的事情怎么样:
let msg = "one:1.0|two:2.0|three:3.0"
let splitKeyVal (str : string) =
match str.Split(':') with
|[|key; value|] -> (key, System.Double.Parse(value))
|_ -> invalidArg "str" "str must have the format key:value"
let createDictionary (str : string) =
str.Split('|')
|> Array.map (splitKeyVal)
|> dict
|> System.Collections.Generic.Dictionary
如果您不介意System.Collections.Generic.Dictionary
返回类型,则可以删除IDictionary
。
如果您希望splitKeyVal
函数失败,那么您最好将其表达为返回选项的函数,例如:
let splitKeyVal (str : string) =
match str.Split(':') with
|[|key; valueStr|] ->
match System.Double.TryParse(valueStr) with
|true, value -> Some (key, value)
|false, _ -> None
|_ -> None
但是你还必须决定如何处理createDictionary
函数中的失败。
答案 1 :(得分:2)
不确定性能方面,但如果您确定自己的输入并且能够“承受”警告,您可以选择:
let d =
msg.Split '|'
|> Array.map (fun s -> let [|key; value|] (*warning here*) = s.Split ':' in key, value)
|> dict
|> System.Collections.Generic.Dictionary // optional if a IDictionary<string, string> suffice