I got given (example) json:
{
"version": 1.1,
"author": "XYZ",
"elements": [{
"type": "nodeX",
"id": 1,
"a": 1,
"b": 2
},
{
"type": "nodeX",
"id": 2,
"a": 1,
"b": 2
},
...
{
"type": "nodeX",
"id": 13214,
"a": 1,
"b": 2
},
{
"type": "nodeY",
"id": 1,
"c": [
"qaz",
"wsx"
]
},
{
"type": "nodeY",
"id": 2,
"c": [
"qaz",
"wsx"
]
},
...
{
"type": "nodeY",
"id": 3,
"c": [
"qaz",
"wsx"
]
}
]
}
Elements list always contain objects with 2 possibility:
- type "nodeX" and properties: id, a and b.
- type "nodeY" and properties: id and c.
I want to get two lists of the given classes:
case class NodeX(val id:Long, val a:Long, val b:Long)
case class NodeY(val id:Long, val c:List[String])
I have tried circe (Scala library) to parse this json to classes:
case class Element(val 'type':String, val id:Long, val a:Option[Long],val b:Option[Long], val c:Option[List[String]])
case class MyJson(val version:Double, val author:String, val elements:List[Element])
but unfortunately i got list of objects Elements with optional fields.
Currently i am using this as workaround:
val elements = // MyJson.elements
for (elem <- elements)
elem match {
case Element("nodeX", _,_,_,_) => //here convert to NodeX and add to list List[NodeX]
case Element("nodeY", _,_,_,_) => //here convert to NodeY and add to list List[NodeY]
}
I am looking for better solution, faster solution because list in this json contains never less than 70k elements.
Thanks in advance :)
another way is dynamic Scala in
Circe
+Monocle
that give you unsafe flexibility of dynamic language:And I believe
circe-generic
auto mode can do the same what described in Andriy Plokhotnyuk's answer.