Преобразовать массив json в список scala - PullRequest
1 голос
/ 10 января 2020

Каков наилучший способ конвертировать Json Array в список scala, а также список Json - это список JsonObject, и у них нет никакого класса в моем коде scala Мне это не нужно , там мой простой json строка

val jsonData = """{
                       |    "store": {
                       |        "book": [
                       |            {
                       |                "category": "reference",
                       |                "author": "Nigel Rees",
                       |                "title": "Sayings of the Century",
                       |                "price": 8.95
                       |            },
                       |            {
                       |                "category": "fiction",
                       |                "author": "Evelyn Waugh",
                       |                "title": "Sword of Honour",
                       |                "price": 12.99
                       |            },
                       |            {
                       |                "category": "fiction",
                       |                "author": "Herman Melville",
                       |                "title": "Moby Dick",
                       |                "isbn": "0-553-21311-3",
                       |                "price": 8.99
                       |            },
                       |            {
                       |                "category": "fiction",
                       |                "author": "J. R. R. Tolkien",
                       |                "title": "The Lord of the Rings",
                       |                "isbn": "0-395-19395-8",
                       |                "price": 22.99
                       |            }
                       |        ],
                       |        "bicycle": {
                       |            "color": "red",
                       |            "price": 19.95
                       |        }
                       |    },
                       |    "expensive": 10
                       |}""".stripMargin

и у меня есть вход json

{   "hello": "$.store.book[?(@.price < 10)]" }

, который говорит получить сверху json список, который удовлетворяет этому критерию

там мой класс, который делает все, что мне нужно:

class CustomConductor {

  def extractRequiredObject[T](jsonString: String)(implicit m: Manifest[T]): T = {
    extractFrom(jsonString) match {
      case Success(jsonParsed) =>
        jsonParsed
      case Failure(exc) =>
        throw new IllegalArgumentException(exc)
    }
  }

  def parsing(headerData: mutable.Map[String, String], jobData: String): Map[String, Any] = {
    var t: Map[String, Any] = Map()
    headerData.foreach{data: (String, Any) =>
      t += (data._1 -> recurse(parse(data._2.toString).values.asInstanceOf[Map[String, Any]], jobData, data._2.toString))
    }
    t
  }

  private def recurse(m: Map[String, Any], data: String, myMap: String): Map[String, Any] = {

    def helper(m: Map[String, Any]): Map[String, Any] = {
      var b = m
      m.foreach(k => {
        k._2 match {
          case str: String if str.startsWith("$") =>
            val res = getDataByJsonPath(data, k._2.toString)
            if (res != null) {
// here I want to check if res is JsonArray of object convert it to List of Map
//              if (res.isInstanceOf[JSONArray]) {
//                val json = parse(res.toString)
//                for (elem <- json.children) {
//                  println(elem)
//                }
//                b += (k._1 -> json.children.toList)
//              }
              b += (k._1 -> res)
            }
          case map: Map[String, Any] =>
            b += (k._1 -> helper(map))
          case _ =>
        }
      })
      b
    }
    helper(m)
  }

  private def extractFrom[T](jsonString:String)(implicit m: Manifest[T]): Try[T] = {
    implicit val formats: DefaultFormats.type = DefaultFormats

    Try {
      parse(jsonString).extract[T]
    }
  }

  private def getDataByJsonPath(jsonString: String, jsonPath: String): Any = {
    val a = JsonPath.read[Any](jsonString, jsonPath)
    if (a.isInstanceOf[JSONArray]) {


      JsonPath.read[List[Any]](jsonString, jsonPath)
    }else
      a
  }

}

преобразование в карту работает нормально, но, как вы видите, привет значение не перечислено JsonArray

Map(hello->[
  {
    "author": "Nigel Rees",
    "price": 8.95,
    "category": "reference",
    "title": "Sayings of the Century"
  },
  {
    "author": "Herman Melville",
    "price": 8.99,
    "isbn": "0-553-21311-3",
    "category": "fiction",
    "title": "Moby Dick"
  }
])))

1 Ответ

1 голос
/ 10 января 2020

Если у вас нет и вам не нужно сопоставлять его с классами дел, вы можете использовать простейшую из известных мне библиотек ujson.

подробнее о: http://www.lihaoyi.com/post/uJsonfastflexibleandintuitiveJSONforScala.html

...