英文:
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.
{
"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
}
}
My data class:
data class Response(
val Items: List<Notification>
........)
data ckass Notification(
val id : String,
val title: String,
val notifications: List<...>,
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:
"Items": {
//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("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"),
// 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("notifications").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<Notification>,
)
data class Notification(
val id: String,
val title: String,
val notifications: List<Any>,
)
// an intermediary object
// I notice that some Notifications are null, hence the `?`
data class ResponseWithObjects(
@JsonProperty("Items") // this is needed for Jackson since I used a conventional variable name Kotlin side
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() // assuming you don't want the null notifications in the resultant array
.toList(),
)
println(desiredResponse)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论