如何将具有对象的 JSON 对象转换为具有对象的 JSON 数组。

huangapple go评论53阅读模式
英文:

How to convert json object with objects to json array with objects

问题

我有一个看起来像这样的JSON对象。

{
  "Items": {
    "zzzz": {
      "id": "zzzz",
      "title": "qqqqqqq",
      "notifications": []
    },
    "rrrrr": {
      "id": "rrrrr",
      "title": "rrrrrrrrrrrrrrrrrr",
      "notifications": []
    },
    "eeeee": {
      "id": "eeeee",
      "title": "eeeeeeeeeeeeeeeeeeee",
      "notifications": []
    },
    "wwww": null,
    "dddddd": {
      "id": "dddddd",
      "title": "ddddddddddddddddddddddddd",
      "notifications": []
    },
    "qqq": {
      "id": "qqq",
      "title": "qqqqqqqqqqqqqqqqqqqqqq",
      "notifications": []
    },
    "rrrrrr": null
  }
}

我的数据类:

data class Response( 
                    val Items: List<Notification>,
                    ........)
data class Notification(
                    val id : String,
                    val title: String,
                    val notifications: List<...>,

我需要一个包含zzzz、rrrr等对象的列表,以便将它们放入数据类中的val items。但我无法弄清楚如何将传入的JSON对象转换为JSON数组。

我想使用自己的反序列化器,但在我的情况下,这并不能帮助我,因为我对所有请求使用okhttp和retrofit的一个实例。而且,响应总是以以下形式从服务器返回:

"Items": {
     //其他请求体
},
.....
}
英文:

I have a json object that looks like this.

{
  &quot;Items&quot;: {
    &quot;zzzz&quot;: {
      &quot;id&quot;: &quot;zzzz&quot;,
      &quot;title&quot;: &quot;qqqqqqq&quot;,
      &quot;notifications&quot;: []
    },
    &quot;rrrrr&quot;: {
      &quot;id&quot;: &quot;rrrrr&quot;,
      &quot;title&quot;: &quot;rrrrrrrrrrrrrrrrrr&quot;,
      &quot;notifications&quot;: []
    },
    &quot;eeeee&quot;: {
      &quot;id&quot;: &quot;eeeee&quot;,
      &quot;title&quot;: &quot;eeeeeeeeeeeeeeeeeeee&quot;,
      &quot;notifications&quot;: []
    },
    &quot;wwww&quot;: null,
    &quot;dddddd&quot;: {
      &quot;id&quot;: &quot;dddddd&quot;,
      &quot;title&quot;: &quot;ddddddddddddddddddddddddd&quot;,
      &quot;notifications&quot;: []
    },
    &quot;qqq&quot;: {
      &quot;id&quot;: &quot;qqq&quot;,
      &quot;title&quot;: &quot;qqqqqqqqqqqqqqqqqqqqqq&quot;,
      &quot;notifications&quot;: []
    },
    &quot;rrrrrr&quot;: null
  }
}

My data class:

data class Response( 
                    val Items: List&lt;Notification&gt;
                    ........)
data ckass Notification(
                    val id : String,
                    val title: String,
                    val notifications: List&lt;...&gt;,

I need a List with objects zzzz,rrrr and so on to get into the data class with val items. But I can't figure out how to convert the incoming json object to a json array

I wanted to use my own deserializer, but in my case it won't help because I use one instance of okhttp and retrofit for all requests. And also, a response always comes from the server in the form of:

  &quot;Items&quot;: {
       //other request body
  },
.....
}

答案1

得分: 0

为了将给定的JSON对象转换为通知对象的列表,您可以遍历"Items"对象中的键值对,并为每个非空值创建一个通知对象。以下是演示此操作的示例Kotlin代码:

val json = // 来自您示例的JSON对象
val itemsObject = json.getJSONObject("Items")
val notifications = mutableListOf<Notification>()
for (key in itemsObject.keys()) {
    val item = itemsObject.getJSONObject(key)
    if (item != null) {
        val notification = Notification(
            item.getString("id"),
            item.getString("title"),
            // 在此处添加解析通知列表的逻辑
        )
        notifications.add(notification)
    }
}
val response = Response(notifications)

请注意,您需要填写解析每个通知对象的"notifications"列表的逻辑。如果它只是一个字符串数组,您可以使用item.getJSONArray("notifications").toList()来获取字符串列表。

英文:

To convert the given JSON object to a list of Notification objects, you can iterate over the key-value pairs in the "Items" object and create a Notification object for each non-null value. Here's some sample Kotlin code that demonstrates this:

    val json = // the JSON object from your example
    val itemsObject = json.getJSONObject(&quot;Items&quot;)
    val notifications = mutableListOf&lt;Notification&gt;()
    for (key in itemsObject.keys()) {
        val item = itemsObject.getJSONObject(key)
        if (item != null) {
            val notification = Notification(
                item.getString(&quot;id&quot;),
                item.getString(&quot;title&quot;),
                // add logic to parse notifications list here
            )
            notifications.add(notification)
        }
    }
    val response = Response(notifications)

Note that you'll need to fill in the logic to parse the "notifications" list for each Notification object. If it's just an array of strings, you can use item.getJSONArray(&quot;notifications&quot;).toList() to get a list of strings.

答案2

得分: 0

以下是翻译好的内容:

"我不确定您使用的反序列化器。假设您正在使用Jackson,这里是一种解决方案,但如果您使用Gson等其他库,也许可以从中借鉴一些思路。

关键思想是使用一个中间对象进行反序列化 - 一个Map,其键值您忽略:

// 您期望的数据类
数据类 Response(
    val items: List<Notification>,
)

数据类 Notification(
    val id: String,
    val title: String,
    val notifications: List<Any>,
)

// 一个中间对象
// 我注意到有些通知是空的,因此使用了 `?`
数据类 ResponseWithObjects(
    @JsonProperty("Items") // 这对于Jackson是必需的,因为我在Kotlin一侧使用了传统的变量名称
    val items: Map<String, Notification?>,
)

fun main(args: Array<String>) {
    val actualResponse: ResponseWithObjects = TestUtils.deserialize("/test.json", ResponseWithObjects::class)
    println(actualResponse)
    val desiredResponse = Response(
        items = actualResponse.items
            .values.filterNotNull() // 假设您不希望在结果数组中包含空通知
            .toList(),
    )
    println(desiredResponse)
}

请注意,代码部分没有进行翻译。

英文:

I am not sure what deserializer you using. Here's a solution assuming Jackson, but maybe you can take the ideas from this if you are using Gson, etc.

The key idea is to use an intermediary object to deserialize into - a Map whose key values you ignore:

// your desired data classes
data class Response(
    val items: List&lt;Notification&gt;,
)

data class Notification(
    val id: String,
    val title: String,
    val notifications: List&lt;Any&gt;,
)

// an intermediary object
// I notice that some Notifications are null, hence the `?`
data class ResponseWithObjects(
    @JsonProperty(&quot;Items&quot;) // this is needed for Jackson since I used a conventional variable name Kotlin side
    val items: Map&lt;String, Notification?&gt;,
)

fun main(args: Array&lt;String&gt;) {
    val actualResponse: ResponseWithObjects = TestUtils.deserialize(&quot;/test.json&quot;, ResponseWithObjects::class)
    println(actualResponse)
    val desiredResponse = Response(
        items = actualResponse.items
            .values.filterNotNull() // assuming you don&#39;t want the null notifications in the resultant array
            .toList(),
    )
    println(desiredResponse)
}

huangapple
  • 本文由 发表于 2023年2月14日 21:24:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75448485.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定