阿尔戈级 Json Array/Object

Scala Argonaut Json Array/Object

我需要使用 scala 和 argonaut 创建这个 json 对象:

   "name_value_list":{
      "created_by":{
          "name":"created_by",
          "value":"1"
       },       
       "name":{
          "name":"name",
          "value":"The Name"
       },
       "securitygroup_primary_group":{
           "name":"securitygroup_primary_group",
           "value":""
     }
  }

我用 scala 创建了这个对象:

Map("name_value_list" -> (
  Map("created_by"-> Map("name" ->"created_by", "value"->"1")),
  Map("name"-> Map("name" ->"name", "value"->"X")),
  Map("securitygroup_primary_group"-> Map("name" ->"securitygroup_primary_group", "value" ->"")))

但是生成的json是这样的:

   "name_value_list":[{
          "created_by":{
              "name":"created_by",
              "value":"1"
           },       
           "name":{
              "name":"name",
              "value":"The Name"
           },
           "securitygroup_primary_group":{
               "name":"securitygroup_primary_group",
               "value":""
         }
      }]

可以帮忙吗?

Map("name_value_list" -> (
  Map("created_by"-> Map("name" ->"created_by", "value"->"1"),
  "name"-> Map("name" ->"name", "value"->"X"),
  "securitygroup_primary_group"-> Map("name" ->"securitygroup_primary_group", "value" ->""))

生成的 JSON 包含一个数组,但您需要一个映射。为了找出哪里出错了,您应该调查在 JSON 编码之前创建的 Scala 类型。

您的代码可以重构为以下内容:

val tuple = (
  Map("created_by" -> Map("name" -> "created_by", "value" -> "1")),
  Map("name" -> Map("name" -> "name", "value" -> "X")),
  Map("securitygroup_primary_group" -> Map("name" -> "securitygroup_primary_group", "value" -> ""))
)
val toEncode = Map(
  "name_value_list" -> tuple
)

其中 tuple 的类型为 Tuple3[Map[String, Map[String, String]], Map[String, Map[String, String]], Map[String, Map[String, String]]]

Argonaut 自然地将元组转换为数组。

为了得到你想要的JSON,你需要把Tuple改成Map:

val notATuple = Map(
  "created_by" -> Map("name" -> "created_by", "value" -> "1"),
  "name" -> Map("name" -> "name", "value" -> "X"),
  "securitygroup_primary_group" -> Map("name" -> "securitygroup_primary_group", "value" -> "")
)

最后的答案是:

val toEncode = Map(
  "name_value_list" -> Map(
    "created_by" -> Map("name" -> "created_by", "value" -> "1"),
    "name" -> Map("name" -> "name", "value" -> "X"),
    "securitygroup_primary_group" -> Map("name" -> "securitygroup_primary_group", "value" -> "")
  )
)

旁注:您可能会发现使用大小写 类 构建数据更容易,然后编写 Codecs 来对它们进行编码。我发现 case 类 比 Maps of Maps of Maps 更容易推理。

从 Argonaut 6.1-M5 开始,您可以使用宏自动从案例 类 中派生编解码器,如下所示:

import argonaut._
implicit val codec = CodecJson.derive[YourCaseClass]