简体   繁体   中英

F#: Using named tuples in JSON

I am new to programming and F# is my first language.

I want to save a tuple of record fields (which I have previously defined) in a JSON file. The end result looks something like this:

"Players": {
    "m_Item1": {
        "Player 1": "ABC",
        "Player 2": "DEF",
        }
    },
    "m_Item2": {
        "Player 1": "GHI",
        "Player 2": "JKL",
        }
    }

Rather than saving the items of the tuple as "m_Item1" and "m_Item2", I'd like to use names of my own choosing -- eg, "First Match" and "Second Match".

How may I do so?

EDIT: Here are the relevant parts of my code:

[<DataContract>]
    type FightSummary = 
        { 
            [<DataMember(Order = 1)>] mutable event: string; 
            [<DataMember(Order = 2)>] mutable winner: string option; 
            [<DataMember(Order = 3)>] mutable loser: string option; 

        }

[<DataContract>]
    type FighterOverallStatsInASpecificFight =
        { 
            [<DataMember(Order = 1)>] mutable fighter: string; 
            [<DataMember(Order = 2)>] mutable opponent: string; 
            [<DataMember(Order = 3, Name = "kd")>] mutable knockdowns: int option; 
            [<DataMember(Order = 4, Name = "sigStrPercent")>] mutable sigStrikePercentage: int option; 
            [<DataMember(Order = 5, Name = "tdPercent")>] mutable takedownPercentage: int option
        }

[<DataContract>]
    type FightInfo = 
        { 
            [<DataMember(Order = 1)>] mutable fightSummary: FightSummary; 
            [<DataMember(Order = 2)>] mutable fighterStats: FighterOverallStatsInASpecificFight * FighterOverallStatsInASpecificFight; 
        }

let internal saveJsonToFile<'t> (someObject:'t) (filePath: string) =   
    use fileStream = new FileStream(filePath, FileMode.OpenOrCreate) 
    (new DataContractJsonSerializer(typeof<'t>)).WriteObject(fileStream, someObject)

FightInfo, when saved in JSON, looks something like this:

[{
    "fightSummary": {
        ...
    },
    "fighterStats": {
        "m_Item1": {
            ...
        },
        "m_Item2": {
            ...
        }
    }]

Rather than "m_Item1" and "m_Item2", I'd like to use names of my own choosing, eg, "Fighter1Stats" and "Fighter2Stats".

I suggest you try using Json.NET as it has a nice F# interface and as you'll see in the code, the syntax is more lightweight than data contract serializer. Look at the copy and update record expression to avoid the mutable unless you absolutely need it.

And finally as for your actual question: introduce the two fighters are properties on the parent records as opposed to having the pair of them as one property.

open Newtonsoft.Json

type FightSummary = 
    { 
        event: string
        winner: string option
        loser: string option
    }

type FighterOverallStatsInASpecificFight =
    { 
        fighter: string
        opponent: string
        [<JsonPropertyAttribute(PropertyName = "kd")>] knockdowns: int option
        [<JsonPropertyAttribute(PropertyName = "sigStrPercent")>] sigStrikePercentage: int option
        [<JsonPropertyAttribute(PropertyName = "tdPercent")>] takedownPercentage: int option
    }

type FightInfo = 
    { 
        fightSummary: FightSummary
        fighter1Stats: FighterOverallStatsInASpecificFight
        fighter2Stats: FighterOverallStatsInASpecificFight
    }


let myFight =
    { fightSummary =
        { event = "MyEvent" 
          winner = None
          loser = None }
      fighter1Stats =
        { fighter = "Hulk"
          opponent = "Hogan"
          knockdowns = None
          sigStrikePercentage = None
          takedownPercentage = None } 
      fighter2Stats =
        { fighter = "Hogan"
          opponent = "Hulk"
          knockdowns = None
          sigStrikePercentage = None
          takedownPercentage = None } }

JsonConvert.SerializeObject(myFight)
|> printfn "%s"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM