带有不同数组类型的Swift Codable [英] Swift Codable with Different Array Types
问题描述
我正在编写一个程序,在其中解析 JSON
数据,其中包括数组数组,其中嵌套的数组具有不同的对象类型(特别是[[String, String,Int]])。例如,
I'm writing a program where I'm parsing JSON
data that includes array of arrays, where the nested arrays have different object types (specifically, [[String, String, Int]]). For example,
{
"number": 5295,
"bets": [
[
"16",
"83",
9
],
[
"75",
"99",
4
],
[
"46",
"27",
5
]
]
}
我正在尝试使用可编码来帮助我解析数据,但是当我尝试某些操作时例如
I'm trying to use codable to help me parse the data, but when I try something like
struct OrderBook: Codable {
let number: Int
let bets: [Bet]
}
struct Bet: Codable {
let price: String
let sale: String
let quantity: Int
}
它给了我一个错误,即
预期对Dictionary
< String,Any>
进行解码,但找到一个数组代替
Expected to decode Dictionary
<String, Any>
but found an array instead
我该如何解决?我无法声明一个空类型的数组。
How do I get around this? I can't declare an array of empty type.
推荐答案
一种解决方案(假设您无法更改JSON)是为实现自定义解码逻辑下注
。为了依次解码每个属性(调用 decode(_:)
的顺序),可以使用一个无密钥的容器(从JSON数组中读取)。
One solution (assuming you can't change the JSON) is to implement custom decoding logic for Bet
. You can use an unkeyed container (which reads from a JSON array) in order to decode each of the properties in turn (the order in which you call decode(_:)
is the order they're expected to appear in the array).
import Foundation
struct OrderBook : Codable {
let number: Int
let bets: [Bet]
}
struct Bet : Codable {
let price: String
let sale: String
let quantity: Int
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
self.price = try container.decode(String.self)
self.sale = try container.decode(String.self)
self.quantity = try container.decode(Int.self)
}
// if you need encoding (if not, make Bet Decodable
// and remove this method)
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(price)
try container.encode(sale)
try container.encode(quantity)
}
}
示例解码:
let jsonString = """
{ "number": 5295, "bets": [["16","83",9], ["75","99",4], ["46","27",5]] }
"""
let jsonData = Data(jsonString.utf8)
do {
let decoded = try JSONDecoder().decode(OrderBook.self, from: jsonData)
print(decoded)
} catch {
print(error)
}
// OrderBook(number: 5295, bets: [
// Bet(price: "16", sale: "83", quantity: 9),
// Bet(price: "75", sale: "99", quantity: 4),
// Bet(price: "46", sale: "27", quantity: 5)
// ])
这篇关于带有不同数组类型的Swift Codable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!