使用Scala Argonaut解析JSON数组

时间:2014-03-18 15:32:52

标签: json scala argonaut

我正在使用Scala& Argonaut,试图解析以下JSON:

[
    {
        "name": "apple",
        "type": "fruit",
        "size": 3
    },
    {
        "name": "jam",
        "type": "condiment",
        "size": 5
    },
    {
        "name": "beef",
        "type": "meat",
        "size": 1
    }
]

努力研究如何迭代并将值提取到List[MyType],其中MyType将具有名称,类型和大小属性。

我会尽快发布更具体的代码(我尝试了很多东西),但基本上我想了解光标的工作方式,以及如何遍历数组等等。我尝试过使用\\ (downArray)移动到数组的头部,然后:->-遍历数组,然后--\(downField)不可用(至少IntelliJ不这么认为)。 所以问题是我如何:

  • 导航到数组
  • 遍历数组(并知道我什么时候完成)
  • 为每个字段提取字符串,整数等值 - jdecode[String]as[String]

3 个答案:

答案 0 :(得分:6)

最简单的方法是为MyType定义编解码器。然后,编译器将愉快地为List[MyType]等构建解码器。我将在这里使用普通类(不是案例类)来明确发生了什么:

class MyType(val name: String, val tpe: String, val size: Int)

import argonaut._, Argonaut._

implicit def MyTypeCodec: CodecJson[MyType] = codec3(
  (name: String, tpe: String, size: Int) => new MyType(name, tpe, size),
  (myType: MyType) => (myType.name, myType.tpe, myType.size)
)("name", "type", "size")

codec3有两个参数列表。第一个参数有两个参数,可以让您告诉如何从MyType创建Tuple3的实例,反之亦然。第二个参数列表允许您指定字段的名称。

现在你可以写下面的内容(如果json是你的字符串):

Parse.decodeValidation[List[MyType]](json)

你已经完成了。

答案 1 :(得分:0)

由于您不需要编码而只是查看解码,您可以按照Travis的建议,但通过实现另一个隐式:MyTypeDecodeJson

implicit def MyTypeDecodeJson: DecodeJson[MyType] = DecodeJson(
    raw => for {
    name     <- raw.get[String]("name")
    type     <- raw.get[String]("type")
    size     <- raw.get[Int]("size")
  } yield MyType(name, type, size))

然后解析你的清单:

Parse.decodeValidation[List[MyType]](jsonString)

答案 2 :(得分:0)

假设MyType是一个case类,那么以下内容也可以工作:

case class MyType(name: String, type: String, size: Int)

object MyType {
    implicit val createCodecJson: CodecJson[MyType] = CodecJson.casecodec3(apply, unapply)(
        "name",
        "type",
        "size"
    )
}