如何在 F# 中将任何记录转换为 map/dictionary?
How convert any record into a map/dictionary in F#?
我需要将任意记录序列化为 maps/dictionary。
我想象我的最终类型是这样的:
type TabularData= array<Map<string, obj>>
但是我在构建接受任何记录并将它们转换为 Map 的通用函数时遇到了问题。
在实践中,最好的建议可能是使用一些现有的序列化库,如 FsPickler。但是,如果您真的想为记录编写自己的序列化,那么 GetRecordFields
(如评论中所述)是可行的方法。
以下获取记录并创建从 string
字段名称到 obj
字段值的映射。请注意,它不处理嵌套记录并且速度不是特别快:
open Microsoft.FSharp.Reflection
let asMap (recd:'T) =
[ for p in FSharpType.GetRecordFields(typeof<'T>) ->
p.Name, p.GetValue(recd) ]
|> Map.ofSeq
这是一个用简单记录调用它的小例子:
type Person =
{ Name : string
Age : int }
asMap { Name = "Tomas"; Age = -1 }
使用 Tomas 提到的相同想法,您可以从这样的记录创建 IDictionary<K,V>
:
let asDictionary (entity: 'T) =
seq {
for prop in FSharpType.GetRecordFields(typeof<'T>) ->
prop.Name, prop.GetValue(entity)
} |> dict
我需要将任意记录序列化为 maps/dictionary。
我想象我的最终类型是这样的:
type TabularData= array<Map<string, obj>>
但是我在构建接受任何记录并将它们转换为 Map 的通用函数时遇到了问题。
在实践中,最好的建议可能是使用一些现有的序列化库,如 FsPickler。但是,如果您真的想为记录编写自己的序列化,那么 GetRecordFields
(如评论中所述)是可行的方法。
以下获取记录并创建从 string
字段名称到 obj
字段值的映射。请注意,它不处理嵌套记录并且速度不是特别快:
open Microsoft.FSharp.Reflection
let asMap (recd:'T) =
[ for p in FSharpType.GetRecordFields(typeof<'T>) ->
p.Name, p.GetValue(recd) ]
|> Map.ofSeq
这是一个用简单记录调用它的小例子:
type Person =
{ Name : string
Age : int }
asMap { Name = "Tomas"; Age = -1 }
使用 Tomas 提到的相同想法,您可以从这样的记录创建 IDictionary<K,V>
:
let asDictionary (entity: 'T) =
seq {
for prop in FSharpType.GetRecordFields(typeof<'T>) ->
prop.Name, prop.GetValue(entity)
} |> dict