F#NameValueCollection to Map

shm*_*111 0 f# json map namevaluecollection mailmessage

我有一个NameValueCollection,我需要将其转换为Map,我无法解决它.我试过了:

let headerMap (m : MailMessage) = m.Headers |> Map.map (fun k v -> v.[k])
Run Code Online (Sandbox Code Playgroud)

我需要使用Seq.map吗?

基本上,我要将System.Net.MailMessage中的头文件序列化为JSON.

Dan*_*iel 5

nvc.AllKeys
|> Seq.map (fun key -> key, nvc.[key])
|> Map.ofSeq
Run Code Online (Sandbox Code Playgroud)


Jac*_* P. 5

丹尼尔的答案会很好,但我想我会提供一些额外的选择:

Array.fold - 这应该比Daniel的版本更快,因为它避免了迭代器的开销.

let mapOfNameValueCollection (collection : NameValueCollection) =
    (Map.empty, collection.AllKeys)
    ||> Array.fold (fun map key ->
        let value = collection.[key]
        Map.add key value map)
Run Code Online (Sandbox Code Playgroud)

带有值集的Array.fold - 与上面的代码类似,但Set<string>如果要确定某个值是否在返回的值集中,则返回值可能很有用.

let mapOfNameValueCollection (collection : NameValueCollection) =
    (Map.empty, collection.AllKeys)
    ||> Array.fold (fun map key ->
        let valueSet =
            match collection.[key] with
            | null ->
                Set.empty
            | values ->
                Set.ofArray <| values.Split [| ',' |]
        Map.add key valueSet map)
Run Code Online (Sandbox Code Playgroud)

递归循环 - 使用递归循环逐项创建映射.我不会在实践中使用它,因为Array.fold版本会更容易,更快.但是,如果您正在使用的特定集合类(派生自NameValueCollection)覆盖该AllKeys属性并且具有一些奇怪的内部行为(需要很长时间才能返回属性值),则此方法可能会更快.

let mapOfNameValueCollection (collection : NameValueCollection) =
    let rec createMap map idx =
        if idx < 0 then map
        else
            let itemName = collection.GetKey idx
            let itemValue = collection.[itemName]
            let map = Map.add itemName itemValue map
            createMap map (idx - 1)

    createMap Map.empty (collection.Count - 1)
Run Code Online (Sandbox Code Playgroud)

命令性循环 - 使用命令循环逐项创建地图.与递归循环一样,我宁愿Array.fold在实践中使用,除非有一些特殊的理由不这样做.

let mapOfNameValueCollection (collection : NameValueCollection) =
    let mutable map = Map.empty

    let maxIndex = collection.Count - 1
    for i = 0 to maxIndex do
        let itemName = collection.GetKey i
        let itemValue = collection.[itemName]
        map <- Map.add itemName itemValue map

    map
Run Code Online (Sandbox Code Playgroud)