How convert any record into a map/dictionary in F#?

1.5k views Asked by At

I need to serialize arbitrary records into maps/dictionary.

I imagine my end type look like this:

type TabularData= array<Map<string, obj>>

But I have problems in build a generic function that accept any record and turn them into Map.

2

There are 2 answers

0
Tomas Petricek On BEST ANSWER

In practice, the best advice is probably to use some existing serialization library like FsPickler. However, if you really want to write your own serialization for records, then GetRecordFields (as mentioned in the comments) is the way to go.

The following takes a record and creates a map from string field names to obj values of the fields. Note that it does not handle nested records and it is not particularly fast:

open Microsoft.FSharp.Reflection

let asMap (recd:'T) = 
  [ for p in FSharpType.GetRecordFields(typeof<'T>) ->
      p.Name, p.GetValue(recd) ]
  |> Map.ofSeq

Here is a little example that calls this with a simple record:

type Person =
  { Name : string 
    Age : int }

asMap { Name = "Tomas"; Age = -1 }
0
Mário Meyrelles On

Using the same idea mentioned by Tomas, you can create a IDictionary<K,V> from a record like this:

let asDictionary (entity: 'T) =
    seq {
        for prop in FSharpType.GetRecordFields(typeof<'T>) -> 
        prop.Name, prop.GetValue(entity)
    } |> dict