这是JSON的形状:
{
"Alice": {
"Age": 30,
"Address": {
"City": "New York",
"State": "NY"
}
},
"Bob": {
"Age": 6,
"Address": {
"City": "Chicago",
"State": "IL"
}
}
}
我想将其反序列化为Map<String, Person>
类型,其中Person
和Address
是记录。人名应该是Map
中的关键字。
我尝试过FSharp.Data
的{{1}},但是它给每个人自己的类型,如下所示:
是否有一个可以更好地处理这种情况的库?
答案 0 :(得分:3)
如果您出于任何原因不想(或不能)使用FSharp.Data,您还可以尝试Thoth.Json,它适用于寓言和普通的.NET。在Thoth中,您可以使用Autoencoders / Autodecoder,如果您的F#类型与使用的JSON非常相似,或者您编写了自己的编码/解码功能,则它将尝试为您处理转换。
一个适合您的用例(如果我正确理解的话)的键入示例(作为控制台应用程序)可能看起来像这样。
let testString = """
{
"Alice": {
"Age": 30,
"Address": {
"City": "New York",
"State": "NY"
}
},
"Bob": {
"Age": 6,
"Address": {
"City": "Chicago",
"State": "IL"
}
}
}
"""
open Thoth.Json.Net
type Address =
{ City : string
State : string }
type Person =
{ Age : int
Address: Address}
let decodeAddress : Decoder<Address> =
Decode.object
(fun get ->
{ City = get.Required.Field "City" Decode.string
State = get.Required.Field "State" Decode.string })
let decodePerson : Decoder<Person> =
Decode.object
(fun get ->
{ Age = get.Required.Field "Age" Decode.int
Address = get.Required.Field "Address" decodeAddress})
let decodeMap jsonString =
Decode.fromString (Decode.keyValuePairs decodePerson) jsonString
|> Result.map (fun namePersonList ->
namePersonList
|> Map.ofList)
[<EntryPoint>]
let main argv =
match decodeMap testString with
| Ok res -> printfn "%A" res
| Error e -> printfn "%s" e
0
答案 1 :(得分:1)
您仍然可以使用FSharp.Data的JsonValue
代替提供程序:
JsonValue.Parse(json).Properties()
|> Seq.iter (printfn "%A")
输出:
("Alice",
{
"Age": 30,
"Address": {
"City": "New York",
"State": "NY"
}
})
("Bob",
{
"Age": 6,
"Address": {
"City": "Chicago",
"State": "IL"
}
})
答案 2 :(得分:1)
正如评论中指出的那样,问题在于您的JSON结构正在使用一条记录来表示人员列表(以名称为键)。如果您可以按照评论中的建议进行更改,那可能是最好的方法。
或者,您仍然可以通过使用类型提供程序为人员定义类型来使用F#Data进行读取:
type Person = JsonProvider<"""{
"Age": 30,
"Address": { "City": "New York", "State": "NY" }
}""">
现在,假设input
是您的多人输入字符串,则可以使用JsonValue
解析器读取它,手动遍历所有顶级记录字段,然后解析您的个人使用新的Person
类型的JSON:
[ for name, person in JsonValue.Parse(input).Properties() ->
name, Person.Root(person) ]
这为您提供了一个元组列表,其中包含每个人的名称和类型化的对象(您将获得类型提供程序的通常好处,即,您可以使用.
访问地址和年龄)