播放 Json 写入:Scala Seq 到 Json 对象
Play Json Writes: Scala Seq to Json Object
在 Scala 中,我有以下数据结构(Item
名称在同一个 Container
中总是唯一的):
case class Container(content: Seq[Item])
case class Item(name: String, elements: Seq[String])
示例实例:
val container = Container(Seq(
Item("A", Seq("A1", "A2")),
Item("B", Seq("B1", "B2"))
))
我想要做的是定义一个 Writes[Container]
产生以下 JSON:
{
"A": ["A1", "A2"],
"B": ["B1", "B2"]
}
我猜测一个可能的解决方案是将Container(Seq[Item])
转换为Map[String, Seq[String]]
,其中每个键对应一个项目的名称,值对应一个item 的元素,然后让 API 完成剩下的工作(可能存在映射的隐式写入,至少在读取 JSON 时是这种情况)。
但是:这种方法为每个 Container
创建了一个新的 Map
,除了生成 JSON 没有其他目的。有很多 Container
个实例需要转换为 JSON,所以我认为这种方法相当昂贵。我还能怎么做?
我认为您不必担心这里的速度(或者至少在担心之前确认这是一个问题),转换为地图可能是最简单的选择。另一种可能效果不佳的替代方法是:
val customWrites: Writes[Container] = new Writes[Container] {
override def writes(container: Container): JsValue = {
val elems = container.content.map(
elem => elem.name -> Json.toJsFieldJsValueWrapper(elem.elements))
Json.obj(elems: _*)
}
}
(显式转换为 JsValueWrapper
- 通常是隐式的 - 在这种情况下似乎是必要的,原因我不完全理解或没有时间深入研究。This answer 有一些细节。)
此方法的一个优点是它将处理 Item
具有重复名称的对象(这当然是合法的 JSON 但会导致与地图发生冲突。)
在 Scala 中,我有以下数据结构(Item
名称在同一个 Container
中总是唯一的):
case class Container(content: Seq[Item])
case class Item(name: String, elements: Seq[String])
示例实例:
val container = Container(Seq(
Item("A", Seq("A1", "A2")),
Item("B", Seq("B1", "B2"))
))
我想要做的是定义一个 Writes[Container]
产生以下 JSON:
{
"A": ["A1", "A2"],
"B": ["B1", "B2"]
}
我猜测一个可能的解决方案是将Container(Seq[Item])
转换为Map[String, Seq[String]]
,其中每个键对应一个项目的名称,值对应一个item 的元素,然后让 API 完成剩下的工作(可能存在映射的隐式写入,至少在读取 JSON 时是这种情况)。
但是:这种方法为每个 Container
创建了一个新的 Map
,除了生成 JSON 没有其他目的。有很多 Container
个实例需要转换为 JSON,所以我认为这种方法相当昂贵。我还能怎么做?
我认为您不必担心这里的速度(或者至少在担心之前确认这是一个问题),转换为地图可能是最简单的选择。另一种可能效果不佳的替代方法是:
val customWrites: Writes[Container] = new Writes[Container] {
override def writes(container: Container): JsValue = {
val elems = container.content.map(
elem => elem.name -> Json.toJsFieldJsValueWrapper(elem.elements))
Json.obj(elems: _*)
}
}
(显式转换为 JsValueWrapper
- 通常是隐式的 - 在这种情况下似乎是必要的,原因我不完全理解或没有时间深入研究。This answer 有一些细节。)
此方法的一个优点是它将处理 Item
具有重复名称的对象(这当然是合法的 JSON 但会导致与地图发生冲突。)