在 F# 中将字符串转换为键值对

pro*_*rth 2 f#

给定一个字符串,例如

一:1.0|二:2.0|三: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 []'
Run Code Online (Sandbox Code Playgroud)

此操作将在一个紧密循环内进行,因此效率将是一个加分项。虽然我也想看到一个简单的解决方案,只是为了让我的 F# 轴承。

谢谢。

The*_*ght 5

这样的事情怎么样:

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

但是,您还必须决定如何处理createDictionary函数中的失败。