如何使用未知密钥解码 json
How to decode json with unknown key
大家,如果其中一个字段未知,如何序列化json结构?
我的 json 是:
{"brands":{"any":false,"19":{"is_all":false,"values":[185,182,178],"include":true},"23":{"is_all":false,"values":[198,199,201],"include":true}},"price":[2000,10000],"year":[1990,2018],"fuel_type":[1,2],"engine_capacity":[\"1.8\",\"4.8\"],"color":[1,2,3],"gearbox_id":[2],"is_georgia":false}
但是:
"19":{"is_all":false,"values":[185,182,178],"include":true}
"23":{"is_all":false,"values":[198,199,201],"include":true}
19 和 23 - 是字符串未知值,由 API 生成。
所以我的结构是:
struct auto_order_model: Decodable {
var brands: brand_details <---- this is problem
let price: [Int]
let year: [Int]
let fuel_type: [Int]
let engine_capacity: [String]
let color: [Int]
let gearbox_id: [Int]
let is_georgia: Bool
}
struct brand_details: Decodable {
var any: Bool
var brand_num: [models]?
}
struct models: Decodable {
var is_all: Bool
var values: [Int]
var include: Bool
}
我这样解码 json:
do {
let data = try JSONDecoder().decode(auto_order_model.self, from: json)
print(data)
}catch {
print("JSON Error")
}
所以,在输出中我得到 nil of brand_num:
▿ auto_order_model #1
▿ brands : brand_details #1
- any : false
- brand_num : nil
▿ price : 2 elements
- 0 : 2000
- 1 : 10000
▿ year : 2 elements
- 0 : 1990
- 1 : 2018
▿ fuel_type : 2 elements
- 0 : 1
- 1 : 2
▿ engine_capacity : 2 elements
- 0 : "1.8"
- 1 : "4.8"
▿ color : 3 elements
- 0 : 1
- 1 : 2
- 2 : 3
▿ gearbox_id : 1 element
- 0 : 2
- is_georgia : false
这是通过为品牌编号动态创建必要的编码键来完成的,如下所示:
struct AutoOrderModel: Decodable {
var brands: BrandList
let price: [Int]
let year: [Int]
let fuelType: [Int]
let engineCapacity: [String]
let color: [Int]
let gearboxId: [Int]
let isGeorgia: Bool
enum CodingKeys: String, CodingKey {
case brands, price, year, color
case fuelType = "fuel_type"
case engineCapacity = "engine_capacity"
case gearboxId = "gearbox_id"
case isGeorgia = "is_georgia"
}
}
struct BrandList: Decodable {
var any: Bool = false
let brands: [String: Models]
struct DetailKey: CodingKey {
var stringValue: String
var intValue: Int?
init?(stringValue: String) {
self.stringValue = stringValue
}
init?(intValue: Int) {
self.stringValue = "\(intValue)";
self.intValue = intValue
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DetailKey.self)
var brands = [String: Models]()
for key in container.allKeys {
if let model = try? container.decode(Models.self, forKey: key) {
brands[key.stringValue] = model
} else if let any = try? container.decode(Bool.self, forKey: key) {
self.any = any
}
}
self.brands = brands
}
}
struct Models: Decodable {
var isAll: Bool
var values: [Int]
var include: Bool
enum CodingKeys: String, CodingKey {
case isAll = "is_all"
case values, include
}
}
大家,如果其中一个字段未知,如何序列化json结构?
我的 json 是:
{"brands":{"any":false,"19":{"is_all":false,"values":[185,182,178],"include":true},"23":{"is_all":false,"values":[198,199,201],"include":true}},"price":[2000,10000],"year":[1990,2018],"fuel_type":[1,2],"engine_capacity":[\"1.8\",\"4.8\"],"color":[1,2,3],"gearbox_id":[2],"is_georgia":false}
但是:
"19":{"is_all":false,"values":[185,182,178],"include":true}
"23":{"is_all":false,"values":[198,199,201],"include":true}
19 和 23 - 是字符串未知值,由 API 生成。
所以我的结构是:
struct auto_order_model: Decodable {
var brands: brand_details <---- this is problem
let price: [Int]
let year: [Int]
let fuel_type: [Int]
let engine_capacity: [String]
let color: [Int]
let gearbox_id: [Int]
let is_georgia: Bool
}
struct brand_details: Decodable {
var any: Bool
var brand_num: [models]?
}
struct models: Decodable {
var is_all: Bool
var values: [Int]
var include: Bool
}
我这样解码 json:
do {
let data = try JSONDecoder().decode(auto_order_model.self, from: json)
print(data)
}catch {
print("JSON Error")
}
所以,在输出中我得到 nil of brand_num:
▿ auto_order_model #1
▿ brands : brand_details #1
- any : false
- brand_num : nil
▿ price : 2 elements
- 0 : 2000
- 1 : 10000
▿ year : 2 elements
- 0 : 1990
- 1 : 2018
▿ fuel_type : 2 elements
- 0 : 1
- 1 : 2
▿ engine_capacity : 2 elements
- 0 : "1.8"
- 1 : "4.8"
▿ color : 3 elements
- 0 : 1
- 1 : 2
- 2 : 3
▿ gearbox_id : 1 element
- 0 : 2
- is_georgia : false
这是通过为品牌编号动态创建必要的编码键来完成的,如下所示:
struct AutoOrderModel: Decodable {
var brands: BrandList
let price: [Int]
let year: [Int]
let fuelType: [Int]
let engineCapacity: [String]
let color: [Int]
let gearboxId: [Int]
let isGeorgia: Bool
enum CodingKeys: String, CodingKey {
case brands, price, year, color
case fuelType = "fuel_type"
case engineCapacity = "engine_capacity"
case gearboxId = "gearbox_id"
case isGeorgia = "is_georgia"
}
}
struct BrandList: Decodable {
var any: Bool = false
let brands: [String: Models]
struct DetailKey: CodingKey {
var stringValue: String
var intValue: Int?
init?(stringValue: String) {
self.stringValue = stringValue
}
init?(intValue: Int) {
self.stringValue = "\(intValue)";
self.intValue = intValue
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DetailKey.self)
var brands = [String: Models]()
for key in container.allKeys {
if let model = try? container.decode(Models.self, forKey: key) {
brands[key.stringValue] = model
} else if let any = try? container.decode(Bool.self, forKey: key) {
self.any = any
}
}
self.brands = brands
}
}
struct Models: Decodable {
var isAll: Bool
var values: [Int]
var include: Bool
enum CodingKeys: String, CodingKey {
case isAll = "is_all"
case values, include
}
}