我如何从 JSON 建模一个结构,其中一些高级属性没有键
How can I model a Struct from JSON where some high level properties don't have keys
我正在尝试创建一个结构来模拟 JSON 的以下位,其中高级属性("Blue Team" 和 "Green Team")没有指定的键。
{
"Teams": [
{
"Blue Team": {
"motto": "We're the best",
"players": [
{
"name": "Bob",
"skill": "jumping really high",
"birthday": 1546326611,
},
{
"name": "Julie",
"skill": "really strong",
"birthday": 1546413133,
},
{
"name": "Kirsten",
"skill": "smarty pants",
"birthday": 1546499716,
}
]
},
"Green Team": {... // same structure as above }
}
]
}
我相信我很接近,但我不确定如何表示 Blue Team
和 Red Team
。这是我目前所拥有的:
struct AllTeams: Codable {
let Teams: [String : Team]
struct Team: Codable {
//let <property>: ???
}
struct ???: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name: String
let skill: String
let birthday: Int // will need to convert this
}
}
更正 json(因为您的 json 不完整并且在生日钥匙末尾包含错误的 ,
)
{
"Teams": [{
"Blue Team": {
"motto": "We're the best",
"players": [{
"name": "Bob",
"skill": "jumping really high",
"birthday": 1546326611
},
{
"name": "Julie",
"skill": "really strong",
"birthday": 1546413133
},
{
"name": "Kirsten",
"skill": "smarty pants",
"birthday": 1546499716
}
]
},
"Green Team": {
"motto": "We're the best",
"players": [{
"name": "Bob",
"skill": "jumping really high",
"birthday": 1546326611
},
{
"name": "Julie",
"skill": "really strong",
"birthday": 1546413133
},
{
"name": "Kirsten",
"skill": "smarty pants",
"birthday": 1546499716
}
]
}
}]
}
2 个键
struct Root: Codable {
let teams: [Team]
enum CodingKeys: String, CodingKey {
case teams = "Teams"
}
}
struct Team: Codable {
let blueTeam, greenTeam: BlueTeamClass
enum CodingKeys: String, CodingKey {
case blueTeam = "Blue Team"
case greenTeam = "Green Team"
}
}
struct BlueTeamClass: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name, skill: String
let birthday: Int
}
对于动态键
struct Root: Codable {
let teams: [[String:Item]]
enum CodingKeys: String, CodingKey {
case teams = "Teams"
}
}
struct Item: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name, skill: String
let birthday: Int
}
解码
do {
let res = try JSONDecoder().decode(Root.self,from:data)
print(res)
}
catch {
print(error)
}
我想你想要 [String: Team]
在你的 AllTeams
结构中?
你可以这样做:
struct AllTeams: Decodable {
let teams: [String: Team]
enum CodingKeys: String, CodingKey {
case teams = "Teams"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
teams = (try container.decode([[String: Team]].self, forKey: .teams))[0]
}
}
struct Team: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name, skill: String
let birthday: Date
}
解码:
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let teams = try! decoder.decode(AllTeams.self, from: json)
print(teams.teams["Blue Team"].motto)
你真的很接近
因为你想将团队解码为字典,将结构更改为
struct AllTeams: Codable {
let Teams: [[String : Team]]
struct Team: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name: String
let skill: String
let birthday: Date
}
}
并解码
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let result = try decoder.decode(AllTeams.self, from: data)
生日整数被解码为Date
有关使用自定义 CodingKey 将团队密钥包含在 Team
结构中的更复杂的解决方案,请查看
注:
我们鼓励您遵守命名约定并添加 CodingKeys 以将 大写 键映射到 小写 结构成员
我正在尝试创建一个结构来模拟 JSON 的以下位,其中高级属性("Blue Team" 和 "Green Team")没有指定的键。
{
"Teams": [
{
"Blue Team": {
"motto": "We're the best",
"players": [
{
"name": "Bob",
"skill": "jumping really high",
"birthday": 1546326611,
},
{
"name": "Julie",
"skill": "really strong",
"birthday": 1546413133,
},
{
"name": "Kirsten",
"skill": "smarty pants",
"birthday": 1546499716,
}
]
},
"Green Team": {... // same structure as above }
}
]
}
我相信我很接近,但我不确定如何表示 Blue Team
和 Red Team
。这是我目前所拥有的:
struct AllTeams: Codable {
let Teams: [String : Team]
struct Team: Codable {
//let <property>: ???
}
struct ???: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name: String
let skill: String
let birthday: Int // will need to convert this
}
}
更正 json(因为您的 json 不完整并且在生日钥匙末尾包含错误的 ,
)
{
"Teams": [{
"Blue Team": {
"motto": "We're the best",
"players": [{
"name": "Bob",
"skill": "jumping really high",
"birthday": 1546326611
},
{
"name": "Julie",
"skill": "really strong",
"birthday": 1546413133
},
{
"name": "Kirsten",
"skill": "smarty pants",
"birthday": 1546499716
}
]
},
"Green Team": {
"motto": "We're the best",
"players": [{
"name": "Bob",
"skill": "jumping really high",
"birthday": 1546326611
},
{
"name": "Julie",
"skill": "really strong",
"birthday": 1546413133
},
{
"name": "Kirsten",
"skill": "smarty pants",
"birthday": 1546499716
}
]
}
}]
}
2 个键
struct Root: Codable {
let teams: [Team]
enum CodingKeys: String, CodingKey {
case teams = "Teams"
}
}
struct Team: Codable {
let blueTeam, greenTeam: BlueTeamClass
enum CodingKeys: String, CodingKey {
case blueTeam = "Blue Team"
case greenTeam = "Green Team"
}
}
struct BlueTeamClass: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name, skill: String
let birthday: Int
}
对于动态键
struct Root: Codable {
let teams: [[String:Item]]
enum CodingKeys: String, CodingKey {
case teams = "Teams"
}
}
struct Item: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name, skill: String
let birthday: Int
}
解码
do {
let res = try JSONDecoder().decode(Root.self,from:data)
print(res)
}
catch {
print(error)
}
我想你想要 [String: Team]
在你的 AllTeams
结构中?
你可以这样做:
struct AllTeams: Decodable {
let teams: [String: Team]
enum CodingKeys: String, CodingKey {
case teams = "Teams"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
teams = (try container.decode([[String: Team]].self, forKey: .teams))[0]
}
}
struct Team: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name, skill: String
let birthday: Date
}
解码:
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let teams = try! decoder.decode(AllTeams.self, from: json)
print(teams.teams["Blue Team"].motto)
你真的很接近
因为你想将团队解码为字典,将结构更改为
struct AllTeams: Codable {
let Teams: [[String : Team]]
struct Team: Codable {
let motto: String
let players: [Player]
}
struct Player: Codable {
let name: String
let skill: String
let birthday: Date
}
}
并解码
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let result = try decoder.decode(AllTeams.self, from: data)
生日整数被解码为Date
有关使用自定义 CodingKey 将团队密钥包含在 Team
结构中的更复杂的解决方案,请查看
注:
我们鼓励您遵守命名约定并添加 CodingKeys 以将 大写 键映射到 小写 结构成员