F#:在 JSON 中使用命名元组

F#: Using named tuples in JSON

我是编程新手,F# 是我的第一语言。

我想在 JSON 文件中保存一个记录字段元组(我之前已定义)。最终结果看起来像这样:

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

我不想将元组的项目保存为 "m_Item1" 和 "m_Item2",而是使用我自己选择的名称——例如 "First Match" 和 "Second Match".

我该怎么做?

编辑:以下是我的代码的相关部分:

[<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,当保存在 JSON 中时,看起来像这样:

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

我想使用自己选择的名称,而不是 "m_Item1" 和 "m_Item2",例如 "Fighter1Stats" 和 "Fighter2Stats"。

我建议你尝试使用 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 来避免 mutable,除非你绝对需要它。

最后关于您的实际问题:介绍这两名战士是父记录中的属性,而不是将他们一对作为一个属性。

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"