Scala循环对象列表

时间:2018-03-06 12:02:16

标签: json scala playframework


我有一个JsObject列表,如:

[{
  "a":"test1",
  "b": 2,
  "c": 5,
  "errors": "Error example"
}]

我想得到类似a:List[Option[String]], b: List[Option[Int]]之类的内容,等等。我需要一个选项,因为并非所有字段都存在。
我的代码是:

jsObjList.map(js => {
  val a = (js \ "a").asOpt[String]
  val b = (js \ "b").asOpt[Int]
  val c = (js \ "c").asOpt[Int]
  val er= (js \ "errors").asOpt[String]
  (a, b, er)
})

我读到了unzipunzip3,但我还没有找到通用函数。

P.S。我正在使用Scala Play进行json解析


谢谢你的帮助!

2 个答案:

答案 0 :(得分:1)

从原始JSON中提取值的类。

case class Foo(a: Option[String], b: Option[Int], c: Option[Int],errors: Option[String])

object Foo {
  // Automatically generate json reader and writer for the class Foo
  implicit val format = Json.format[Foo]
}

将隐含值保存在Foo的伴随对象中会使Scala在需要时自动获取隐式值。

将JSON解析为案例类实例列表的代码

 payload.validate[List[Foo]]

如果您预计有任何解析错误,请使用validateOpt

payload.validateOpt[List[Foo]]

Scala REPL

scala> :paste
// Entering paste mode (ctrl-D to finish)


val str = """
[{
  "a":"test1",
  "b": 2,
  "c": 5,
  "errors": "Error example"
}]
"""

// Exiting paste mode, now interpreting.

str: String =
"
[{
  "a":"test1",
  "b": 2,
  "c": 5,
  "errors": "Error example"
}]
"

scala> val payload = Json.parse(str)
payload: play.api.libs.json.JsValue = [{"a":"test1","b":2,"c":5,"errors":"Error example"}]

scala> case class Foo(a: Option[String], b: Option[Int], c: Option[Int],errors: Option[String])
defined class Foo

scala> implicit val format = Json.format[Foo]
format: play.api.libs.json.OFormat[Foo] = play.api.libs.json.OFormat$$anon$1@53a0b0a3

scala> payload.validate[List[Foo]]
res5: play.api.libs.json.JsResult[List[Foo]] = JsSuccess(List(Foo(Some(test1),Some(2),Some(5),Some(Error example))),)

答案 1 :(得分:0)

您可以使用包含名为implicit val format = Json.format[*your class*]的特殊val的伴随对象将JSON解析为Scala案例类。

以下是与您类似的示例:

import play.api.libs.json.Json

val body =
  """{
    |  "a":"my string",
    |  "b": 1,
    |  "c": 2
    |}
  """.stripMargin

val body2 =
  """{
    |  "a":"my string",
    |  "c": 5
    |}
  """.stripMargin

case class MyClass(a: Option[String], b: Option[Int], c: Option[Int])

object MyClass {
  implicit val format = Json.format[MyClass]
}

使用此功能,调用Json.parse(body).as[MyClass]即可:

res0: MyClass = MyClass(Some(my string),Some(2),Some(5))

使用缺少的字段调用此Json.parse函数(假设它们是可选的),例如Json.parse(body2).as[MyClass]给出:

res1: MyClass = MyClass(Some(my string),None,Some(5))

如果其中一个缺少的字段不是可选的,则此解析将不起作用。