使用 Swift 中的变量解码 JSON
Decode JSON with variables in Swift
我正在尝试解码 JSON-Swift
中的此类数据
{"Total ingredients":[{"PE-LLD":"54.4 %"},{"PE-HD":"41.1 %"},{"TiO2":"4.5 %"}]}
成分的名称和数量是可变的。因此我只能用这种结构解码它:
struct Product: Codable {
var total_ingredients: [[String: String]]?
private enum CodingKeys : String, CodingKey {
case total_ingredients = "Total ingredients"
}
}
但我希望能够在任一字典中解码它:var total_ingredients: [String: String]?
或我在对象数组中的首选:var total_ingredients: [Ingredient]?
struct Ingredient: Codable {
var name: String
var percentage: String
}
我已经尝试使用扩展来解决我的问题,但它不起作用,我认为这不是正确的方法:
extension Ingredient {
init(_ ingredient: [String: String]) {
var key: String = ""
var value: String = ""
for data in ingredient {
key = data.key
value = data.value
}
self = .init(name: key, percentage: value)
}
}
提前致谢:)
您必须实施 init(from decoder
并将字典数组映射到 Ingredient
个实例
struct Product: Decodable {
let totalIngredients: [Ingredient]
private enum CodingKeys : String, CodingKey { case totalIngredients = "Total ingredients" }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let ingredientData = try container.decode([[String:String]].self, forKey: .totalIngredients)
totalIngredients = ingredientData.compactMap({ dict -> Ingredient? in
guard let key = dict.keys.first, let value = dict[key] else { return nil }
return Ingredient(name: key, percentage: value)
})
}
}
struct Ingredient {
let name, percentage: String
}
let jsonString = """
{"Total ingredients":[{"PE-LLD":"54.4 %"},{"PE-HD":"41.1 %"},{"TiO2":"4.5 %"}]}
"""
let data = Data(jsonString.utf8)
do {
let result = try JSONDecoder().decode(Product.self, from: data)
print(result)
} catch {
print(error)
}
不需要扩展。
我正在尝试解码 JSON-Swift
中的此类数据{"Total ingredients":[{"PE-LLD":"54.4 %"},{"PE-HD":"41.1 %"},{"TiO2":"4.5 %"}]}
成分的名称和数量是可变的。因此我只能用这种结构解码它:
struct Product: Codable {
var total_ingredients: [[String: String]]?
private enum CodingKeys : String, CodingKey {
case total_ingredients = "Total ingredients"
}
}
但我希望能够在任一字典中解码它:var total_ingredients: [String: String]?
或我在对象数组中的首选:var total_ingredients: [Ingredient]?
struct Ingredient: Codable {
var name: String
var percentage: String
}
我已经尝试使用扩展来解决我的问题,但它不起作用,我认为这不是正确的方法:
extension Ingredient {
init(_ ingredient: [String: String]) {
var key: String = ""
var value: String = ""
for data in ingredient {
key = data.key
value = data.value
}
self = .init(name: key, percentage: value)
}
}
提前致谢:)
您必须实施 init(from decoder
并将字典数组映射到 Ingredient
个实例
struct Product: Decodable {
let totalIngredients: [Ingredient]
private enum CodingKeys : String, CodingKey { case totalIngredients = "Total ingredients" }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let ingredientData = try container.decode([[String:String]].self, forKey: .totalIngredients)
totalIngredients = ingredientData.compactMap({ dict -> Ingredient? in
guard let key = dict.keys.first, let value = dict[key] else { return nil }
return Ingredient(name: key, percentage: value)
})
}
}
struct Ingredient {
let name, percentage: String
}
let jsonString = """
{"Total ingredients":[{"PE-LLD":"54.4 %"},{"PE-HD":"41.1 %"},{"TiO2":"4.5 %"}]}
"""
let data = Data(jsonString.utf8)
do {
let result = try JSONDecoder().decode(Product.self, from: data)
print(result)
} catch {
print(error)
}
不需要扩展。