Scala Argonaut 在列表中折叠?
Scala Argonaut folding across a list?
我是 Argonaut 的新手(我被迫使用它,因为代码库较旧,使用的是旧版本的 scalaz,而且我们无意更新它,因为我们正在重写来自从头开始),我正在尝试找到一种方法将一些数据转储到 JSON.
我有一个案例 class 叫做 Magnitude
。为简单起见,定义为:
case class Magnitude(bandname: String)
我想要的是一个接受 List[Magnitude]
并输出 Json
的函数,我可以将它与其他 Json
.
链接在一起
现在,我在做:
def magnitudeFields(magnitudes: List[Magnitude]): Json =
magnitudes.foldLeft(jEmptyObject) { case (j, m) =>
("bandName" := m.bandname) ->: j
}
然后说我有一个 List[Magnitude]
:
的实例化
val magList = List(Magnitude("R"), Magnitude("J"), Magnitude("_uc"), Magnitude("K"))
当我打电话给 magnitudeFields(magList)
时:
... previousJsonData ->: ('magnitudes' := magnitudeFields(magList)) ->: nextJsonData ...
我只收到 bandName: K
,前面的其他三个条目不是函数输出的 JSON 的一部分:
"magnitudes" : {
"bandName" : "K"
},
而不是我想要的,即:
"magnitudes" : {
"bandName" : "R"
"bandName" : "J"
"bandName" : "_uc"
"bandName" : "K"
},
如有任何帮助,我们将不胜感激。我怀疑我使用 jEmptyObject
作为 foldLeft
的默认值做错了什么,并且可能需要在某些时候使用 jArray
之类的东西(函数返回 List[Json]
相反,但我不确定我应该怎么做。
您应该只为 Magnitude
定义一个 EncodeJson
实例,然后让 Argonaut 处理其余的逻辑:
import argonaut._, Argonaut._
case class Magnitude(bandname: String)
object Magnitude {
implicit val encode: EncodeJson[Magnitude] =
EncodeJson { m =>
jSingleObject("bandName", jString(m.bandname))
}
}
object Main {
val magList = List(Magnitude("R"), Magnitude("J"), Magnitude("_uc"), Magnitude("K"))
def main(args: Array[String]): Unit = {
val prefix = "prefix" := "prefix"
val suffix = "suffix" := "suffix"
val json = prefix ->: ("magnitudes" := magList) ->: suffix ->: jEmptyObject
println(json.asJson.spaces2)
//{
// "prefix" : "prefix",
// "magnitudes" : [
// {
// "bandName" : "R"
// },
// {
// "bandName" : "J"
// },
// {
// "bandName" : "_uc"
// },
// {
// "bandName" : "K"
// }
// ],
// "suffix" : "suffix"
//}
}
}
我是 Argonaut 的新手(我被迫使用它,因为代码库较旧,使用的是旧版本的 scalaz,而且我们无意更新它,因为我们正在重写来自从头开始),我正在尝试找到一种方法将一些数据转储到 JSON.
我有一个案例 class 叫做 Magnitude
。为简单起见,定义为:
case class Magnitude(bandname: String)
我想要的是一个接受 List[Magnitude]
并输出 Json
的函数,我可以将它与其他 Json
.
现在,我在做:
def magnitudeFields(magnitudes: List[Magnitude]): Json =
magnitudes.foldLeft(jEmptyObject) { case (j, m) =>
("bandName" := m.bandname) ->: j
}
然后说我有一个 List[Magnitude]
:
val magList = List(Magnitude("R"), Magnitude("J"), Magnitude("_uc"), Magnitude("K"))
当我打电话给 magnitudeFields(magList)
时:
... previousJsonData ->: ('magnitudes' := magnitudeFields(magList)) ->: nextJsonData ...
我只收到 bandName: K
,前面的其他三个条目不是函数输出的 JSON 的一部分:
"magnitudes" : {
"bandName" : "K"
},
而不是我想要的,即:
"magnitudes" : {
"bandName" : "R"
"bandName" : "J"
"bandName" : "_uc"
"bandName" : "K"
},
如有任何帮助,我们将不胜感激。我怀疑我使用 jEmptyObject
作为 foldLeft
的默认值做错了什么,并且可能需要在某些时候使用 jArray
之类的东西(函数返回 List[Json]
相反,但我不确定我应该怎么做。
您应该只为 Magnitude
定义一个 EncodeJson
实例,然后让 Argonaut 处理其余的逻辑:
import argonaut._, Argonaut._
case class Magnitude(bandname: String)
object Magnitude {
implicit val encode: EncodeJson[Magnitude] =
EncodeJson { m =>
jSingleObject("bandName", jString(m.bandname))
}
}
object Main {
val magList = List(Magnitude("R"), Magnitude("J"), Magnitude("_uc"), Magnitude("K"))
def main(args: Array[String]): Unit = {
val prefix = "prefix" := "prefix"
val suffix = "suffix" := "suffix"
val json = prefix ->: ("magnitudes" := magList) ->: suffix ->: jEmptyObject
println(json.asJson.spaces2)
//{
// "prefix" : "prefix",
// "magnitudes" : [
// {
// "bandName" : "R"
// },
// {
// "bandName" : "J"
// },
// {
// "bandName" : "_uc"
// },
// {
// "bandName" : "K"
// }
// ],
// "suffix" : "suffix"
//}
}
}