![](/img/trans.png)
[英]How to define SingleOrArrayConverter to Handle JSON property in F# ( Port from C# )
[英]F# Data JSON type provider: How to handle a JSON property that can be an array or a property?
我正在使用F#Data库中的JSON类型提供程序从API访问JSON文档。 文档包含一个属性(让我们称之为'car'),有时候是一个对象数组,有时候是一个对象。 这是:
'car': [
{ ... },
{ ... }
]
或这个:
'car': { ... }
{ ... }
的对象在两种情况下都具有相同的结构。
JSON类型提供程序指示属性的类型为:
JsonProvider<"../data/sample.json">.ArrayOrCar
其中sample.json
是我的示例文档。
我的问题是:我怎样才能弄清楚属性是一个数组(以便我可以将它作为数组处理)还是单个对象(以便我可以将它作为一个对象处理)?
更新:简化的示例JSON将如下所示:
{
"set": [
{
"car": [
{
"brand": "BMW"
},
{
"brand": "Audi"
}
]
},
{
"car": {
"brand": "Toyota"
}
}
]
}
并且使用以下代码将指出doc.Set.[0].Car
的类型是JsonProvider<...>.ArrayOrCar
:
type example = JsonProvider<"sample.json">
let doc = example.GetSample()
doc.Set.[0].Car
如果数组中JSON值的类型与直接嵌套的JSON值的类型相同,那么JSON类型提供程序实际上将统一这两种类型,因此您可以使用相同的函数处理它们。
以最小的JSON文档为例,以下工作原理:
type J = JsonProvider<"sample.json">
// The type `J.Car` is the type of the car elements in the array
// but also of the car record directly nested in the "car" field
let printBrand (car:J.Car) =
printfn "%s" car.Brand
// Now you can use pattern matching to check if the current element
// has an array of cars or just a single record - then you can call
// `printBrand` either on all cars or on just a single car
let doc = J.GetSample()
for set in doc.Set do
match set.Car.Record, set.Car.Array with
| Some c, _ -> printBrand c
| _, Some a -> for c in a do printBrand c
| _ -> failwith "Wrong input"
在玩完图书馆之后,我发现你可以这样做:
let car = doc.Set.[0].Car
let processObject (car:example.ArrayOrCar) =
match car.Array with
| Some a -> printfn "do stuff with an array %A" a
| None -> match car.Record with
| Some c -> printfn "do stuff with an object %A" c
| None -> printfn "fail here?"
要处理整个Set[]
您可以使用像Array.map
这样的Array.map
将processObject应用于每个元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.