我正在尝试解析JSON API,我试图提取关键值" data"的数字。如您所见,这些图形嵌套在两个数组中,其中第二个数组没有要引用的键值。我该怎么做?
{
"dataset": {
"id": 9789340,
"name": "DCC share price (DCC), Currency GBX",
"description": "Stock Prices for Dcc Share Price (dcc), Currency Gbx from the London Stock Exchange.<br><br>Currency: GBX",
"start_date": "2006-03-16",
"end_date": "2017-11-22",
"column_names": [
"Date",
"Price",
"High",
"Low",
"Volume",
"Last Close",
"Change",
"Var%"
],
"data": [
[
"2017-11-22",
7060.0,
7185.0,
7045.0,
156444.0,
7060.0,
-95.0,
-1.33
],
[
"2017-11-21",
7155.0,
7210.0,
7130.0,
189002.0,
7155.0,
-30.0,
-0.42
],
]
}
到目前为止,我已经做到了这一点。
struct Dataset: Decodable {
let name: String
let description: String
let column_names: [ColumnNames]
let data: [StockData]
}
struct ColumnNames: Decodable {
// What happens here??
}
struct StockData: Decodable {
// What happens here??
}
guard let url = URL(string : jsonUrlString) else
{ return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let jsonData = data else { return }
do{
let dataSet = try JSONDecoder().decode(Dataset.self, from: jsonData)
let dataArray = dataset.data
dump(dataArray)
for stockDataArray in dataArray {
for stockItems in stockDataArray
dump(stockItems)
}
}
正如您所看到的,我不知道如何解码&#34; StockData&#34;因为JSON数据是一个数组数组。如果我已经回答了这个问题,那么希望我能够解决#34; ColumnNames&#34;应该解析。它也不是具有要解析的键值的字典。
答案 0 :(得分:1)
这是使用JSONDecoder
它会创建合并column_names
和data
数组的词典。
这是你的JSON
let jsonString = """
{
"dataset": {
"id": 9789340,
"name": "DCC share price (DCC), Currency GBX",
"description": "Stock Prices for Dcc Share Price (dcc), Currency Gbx from the London Stock Exchange.<br><br>Currency: GBX",
"start_date": "2006-03-16",
"end_date": "2017-11-22",
"column_names": ["Date", "Price", "High", "Low", "Volume", "Last Close", "Change", "Var%"],
"data": [["2017-11-22", 7060.0, 7185.0, 7045.0, 156444.0, 7060.0, -95.0, -1.33],
["2017-11-21", 7155.0, 7210.0, 7130.0, 189002.0, 7155.0, -30.0, -0.42]]
}
}
"""
和两个结构,一个用于根对象,一个用于Dataset
,在此示例中仅id
和name
被解码,data
将包含合并的数组字典
struct Root : Decodable {
let dataset : Dataset
}
struct Dataset : Decodable {
private enum CodingKeys : String, CodingKey {
case id, name, columnNames = "column_names", data
}
let id : Int
let name : String
var data = [[String:Any]]()
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
let columnNames = try container.decode([String].self, forKey: .columnNames)
var outerContainer = try container.nestedUnkeyedContainer(forKey: .data)
while !outerContainer.isAtEnd {
var columnIndex = 0
var dataSet = [String:Any]()
var innerContainer = try outerContainer.nestedUnkeyedContainer()
let date = try innerContainer.decode(String.self)
var key = columnNames[columnIndex]
dataSet[key] = date
columnIndex += 1
while !innerContainer.isAtEnd {
let value = try innerContainer.decode(Double.self)
key = columnNames[columnIndex]
dataSet[key] = value
columnIndex += 1
}
data.append(dataSet)
}
}
}
现在解码这些东西
let data = Data(jsonString.utf8)
do {
let decoder = JSONDecoder()
let root = try decoder.decode(Root.self, from: data)
print(root.dataset)
} catch {
print("error: ", error)
}