如何解码多种类型的嵌套数组?
How can I decode a nested array of multiple types?
这是我的JSON
{
"response":[
[
{
"neededValue" : "Something I really need"
},
567890812309,
"Some text. Bla bla bla",
{
"Garbage" : "Garbage I do not need"
}
]
]
}
它包含一个带有两个字典的数组,一个 Int 和一个 String。我需要解码第一本字典。我试过这个:
struct response: Decodable {
var response: [[String : String]]
}
但这显然没有捕获String值和Int值。我该如何描述数组?请帮忙
import Foundation
let str = """
{
"response":
[
[
{
"neededValue" : "Something I really need"
},
567890812309,
"Some text. Bla bla bla",
{
"Garbage" : "Garbage I don't need"
}
]
]
}
"""
let data = str.data(using: .utf8)!
struct NeededValue: Decodable {
let neededValue: String
}
struct Garbage: Decodable {
let garbage = ""
enum CodingKeys: String, CodingKey {
case garbage = "Garbage"
}
}
struct Response: Decodable {
let neededValue: NeededValue
let intValue: Int
let stringValue: String
let garbageValue: Garbage
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
neededValue = try container.decode(NeededValue.self)
intValue = try container.decode(Int.self)
stringValue = try container.decode(String.self)
garbageValue = try container.decode(Garbage.self)
}
}
struct Container: Decodable {
let response: [Response]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
response = try container.decode([Response].self, forKey: .response)
}
enum CodingKeys: String, CodingKey {
case response
}
}
do {
let res = try JSONDecoder().decode(Container.self, from: data)
print(res)
} catch {
print(error)
}
顺便说一句,使用这个 link Whosebug 来改进答案。com/a/47215561/5555803 更好的方法是这样的:
struct Response: Decodable {
var value: Any?
init(from decoder: Decoder) throws {
if let int = try? Int(from: decoder) {
value = int
} else if let string = try? String(from: decoder) {
value = string
} else if let neededValue = try? NeededValue(from: decoder) {
value = neededValue
} else if let garbage = try? Garbage(from: decoder) {
value = garbage
}
}
}
struct ResponseChild: Decodable {
var response: [[Response]]?
}
do {
let res = try JSONDecoder().decode(ResponseChild.self, from: data)
print(res)
} catch {
print(error)
}
这是我的JSON
{
"response":[
[
{
"neededValue" : "Something I really need"
},
567890812309,
"Some text. Bla bla bla",
{
"Garbage" : "Garbage I do not need"
}
]
]
}
它包含一个带有两个字典的数组,一个 Int 和一个 String。我需要解码第一本字典。我试过这个:
struct response: Decodable {
var response: [[String : String]]
}
但这显然没有捕获String值和Int值。我该如何描述数组?请帮忙
import Foundation
let str = """
{
"response":
[
[
{
"neededValue" : "Something I really need"
},
567890812309,
"Some text. Bla bla bla",
{
"Garbage" : "Garbage I don't need"
}
]
]
}
"""
let data = str.data(using: .utf8)!
struct NeededValue: Decodable {
let neededValue: String
}
struct Garbage: Decodable {
let garbage = ""
enum CodingKeys: String, CodingKey {
case garbage = "Garbage"
}
}
struct Response: Decodable {
let neededValue: NeededValue
let intValue: Int
let stringValue: String
let garbageValue: Garbage
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
neededValue = try container.decode(NeededValue.self)
intValue = try container.decode(Int.self)
stringValue = try container.decode(String.self)
garbageValue = try container.decode(Garbage.self)
}
}
struct Container: Decodable {
let response: [Response]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
response = try container.decode([Response].self, forKey: .response)
}
enum CodingKeys: String, CodingKey {
case response
}
}
do {
let res = try JSONDecoder().decode(Container.self, from: data)
print(res)
} catch {
print(error)
}
顺便说一句,使用这个 link Whosebug 来改进答案。com/a/47215561/5555803 更好的方法是这样的:
struct Response: Decodable {
var value: Any?
init(from decoder: Decoder) throws {
if let int = try? Int(from: decoder) {
value = int
} else if let string = try? String(from: decoder) {
value = string
} else if let neededValue = try? NeededValue(from: decoder) {
value = neededValue
} else if let garbage = try? Garbage(from: decoder) {
value = garbage
}
}
}
struct ResponseChild: Decodable {
var response: [[Response]]?
}
do {
let res = try JSONDecoder().decode(ResponseChild.self, from: data)
print(res)
} catch {
print(error)
}