如何在同一容器中解码 DynamicKeys 和 CodingKeys?
How to decode DynamicKeys & CodingKeys in the same container?
考虑以下 JSON: 我正在尝试解码“teams”对象。
let jsonString = """
{
"Superheroes":{
"Marvel":"107",
"DC":"106"
},
"teams":{
"106":{
"name":"Marvel",
"Superheroes":{
"890":{
"name":"Batman"
}
}
},
"107":{
"name":"DC",
"Superheroes":{
"891":{
"name":"Wonder Woman"
}
}
}
}
}
"""
我试过这样的事情:
struct SuperheroResponse: Decodable {
let teams: [Team]
private enum CodingKeys: String, CodingKey {
case teams = "teams"
}
private struct DynamicCodingKeys: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int?
init?(intValue: Int) {
return nil
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let teamContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.teams)
print(teamContainer.allKeys.count)
let tempArray: [Team] = []
for key in teamContainer.allKeys {
let decodedObject = try teamContainer.decode(Team.self, forKey: DynamicCodingKeys(stringValue: key.stringValue)!)
tempArray.append(decodedObject)
}
teams = tempArray
}
}
struct Team: Decodable {
let name: String
}
我想首先我会得到团队容器,映射到键上,然后从那里继续。问题是 teamContainer.allKeys.count 始终为零。
还有以下行,导致以下错误:无法将类型 'SuperheroResponse.DynamicCodingKeys' 的值转换为预期的参数类型 'SuperheroResponse.CodingKeys'
let decodedObject = try teamContainer.decode(Team.self, forKey: DynamicCodingKeys(stringValue: key.stringValue)!)
最后我解码如下:
let jsonData = Data(jsonString.utf8)
let decodedResult = try! JSONDecoder().decode(SuperheroResponse.self, from: jsonData)
dump(decodedResult)
如有任何帮助,我们将不胜感激。理想情况下,我想要像 SuperheroResponse -> [Team] 这样的东西,
团队 -> 姓名,[超级英雄],超级英雄 -> 姓名
你只是犯了几个小错误。你快到了。
团队容器由 DynamicCodingKeys 键控:
let teamContainer = try container.nestedContainer(keyedBy: DynamicCodingKeys.self, // <=
forKey: .teams)
并且可以使用您提供的密钥对 Teams 进行解码:
let decodedObject = try teamContainer.decode(Team.self, forKey: key)
此外,tempArray
需要为 var:
var tempArray: [Team] = []
或用 map
替换该循环:
teams = try teamContainer.allKeys.map {
try teamContainer.decode(Team.self, forKey: [=13=])
}
总计:
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let teamContainer = try container.nestedContainer(keyedBy: DynamicCodingKeys.self, forKey: .teams)
teams = try teamContainer.allKeys.map {
try teamContainer.decode(Team.self, forKey: [=14=])
}
}
考虑以下 JSON: 我正在尝试解码“teams”对象。
let jsonString = """
{
"Superheroes":{
"Marvel":"107",
"DC":"106"
},
"teams":{
"106":{
"name":"Marvel",
"Superheroes":{
"890":{
"name":"Batman"
}
}
},
"107":{
"name":"DC",
"Superheroes":{
"891":{
"name":"Wonder Woman"
}
}
}
}
}
"""
我试过这样的事情:
struct SuperheroResponse: Decodable {
let teams: [Team]
private enum CodingKeys: String, CodingKey {
case teams = "teams"
}
private struct DynamicCodingKeys: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int?
init?(intValue: Int) {
return nil
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let teamContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.teams)
print(teamContainer.allKeys.count)
let tempArray: [Team] = []
for key in teamContainer.allKeys {
let decodedObject = try teamContainer.decode(Team.self, forKey: DynamicCodingKeys(stringValue: key.stringValue)!)
tempArray.append(decodedObject)
}
teams = tempArray
}
}
struct Team: Decodable {
let name: String
}
我想首先我会得到团队容器,映射到键上,然后从那里继续。问题是 teamContainer.allKeys.count 始终为零。
还有以下行,导致以下错误:无法将类型 'SuperheroResponse.DynamicCodingKeys' 的值转换为预期的参数类型 'SuperheroResponse.CodingKeys'
let decodedObject = try teamContainer.decode(Team.self, forKey: DynamicCodingKeys(stringValue: key.stringValue)!)
最后我解码如下:
let jsonData = Data(jsonString.utf8)
let decodedResult = try! JSONDecoder().decode(SuperheroResponse.self, from: jsonData)
dump(decodedResult)
如有任何帮助,我们将不胜感激。理想情况下,我想要像 SuperheroResponse -> [Team] 这样的东西, 团队 -> 姓名,[超级英雄],超级英雄 -> 姓名
你只是犯了几个小错误。你快到了。
团队容器由 DynamicCodingKeys 键控:
let teamContainer = try container.nestedContainer(keyedBy: DynamicCodingKeys.self, // <=
forKey: .teams)
并且可以使用您提供的密钥对 Teams 进行解码:
let decodedObject = try teamContainer.decode(Team.self, forKey: key)
此外,tempArray
需要为 var:
var tempArray: [Team] = []
或用 map
替换该循环:
teams = try teamContainer.allKeys.map {
try teamContainer.decode(Team.self, forKey: [=13=])
}
总计:
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let teamContainer = try container.nestedContainer(keyedBy: DynamicCodingKeys.self, forKey: .teams)
teams = try teamContainer.allKeys.map {
try teamContainer.decode(Team.self, forKey: [=14=])
}
}