我有一个 NameValueCollection,我需要将其转换为 Map,但我无法解决。我试过:
let headerMap (m : MailMessage) = m.Headers |> Map.map (fun k v -> v.[k])
我需要改用 Seq.map 吗?
基本上,我想将 System.Net.MailMessage 中的标头序列化为 JSON。
我有一个 NameValueCollection,我需要将其转换为 Map,但我无法解决。我试过:
let headerMap (m : MailMessage) = m.Headers |> Map.map (fun k v -> v.[k])
我需要改用 Seq.map 吗?
基本上,我想将 System.Net.MailMessage 中的标头序列化为 JSON。
nvc.AllKeys
|> Seq.map (fun key -> key, nvc.[key])
|> Map.ofSeq
丹尼尔的回答会很好,但我想我会提供一些额外的选择:
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)
带有值集的 Array.fold - 类似于上面的代码,但将值作为 a 返回,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)
递归循环——使用递归循环逐项创建地图。我不会在实践中使用它,因为该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)
命令式循环——使用命令式循环逐项创建地图。与递归循环一样,我更愿意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