3

与えられた(例)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"
            ]
        }
    ]
}

要素リストには常に次の 2 つの可能性のあるオブジェクトが含まれます。

  • nodeX」と入力し、プロパティ: ida 、およびb
  • タイプ「nodeY」およびプロパティ: idおよびc

指定されたクラスの 2 つのリストを取得したい:

case class NodeX(val id:Long, val a:Long, val b:Long)
case class NodeY(val id:Long, val c:List[String])

このjsonをクラスに解析するために、circe(Scalaライブラリ)を試しました:

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])

残念ながら、オプションのフィールドを持つオブジェクト要素のリストを取得しました。
現在、私はこれを回避策として使用しています:

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]
    }

このjsonのリストには70k以上の要素が含まれていないため、より良い解決策、より高速な解決策を探しています。

前もって感謝します :)

4

2 に答える 2

-1

封印された特性を持つADTとして定義NodeXおよびNodeYクラス化することが許可されている場合、それはjsoniter-scalaによって簡単に解析できます。

ライブラリを依存関係リストに追加します

libraryDependencies ++= Seq(
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "0.29.2" % Compile, 
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "0.29.2" % Provided // required only in compile-time
)

ケース クラスを定義します。

sealed trait Node
final case class NodeX(val id:Long, val a:Long, val b:Long) extends Node
final case class NodeY(val id:Long, val c:List[String]) extends Node

case class MyJson(val version:Double, val author:String, val elements:List[Node])

ルート ケース クラスのコーデックを生成して使用する

import java.io._
import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._

val myJsonCodec = JsonCodecMaker.make[MyJson](CodecMakerConfig())

val myJson = {
  val fin = new FileInputStream("/tmp/my.json")
  try readFromStream(codec, fin)
  finally fin.close()
}
于 2018-02-07T12:55:40.290 に答える