【发布时间】:2021-09-26 00:36:53
【问题描述】:
我正在尝试学习如何在 Swift 中使用 Dictionary。我的程序读取一个本地 JSON 文件,该文件包含每个键的五个值元素,并将其放入字典中。键是字符串格式“yyyy-MM-dd”的日期,值表示字符串格式的美元 409.34593。我已经能够对字典进行排序和过滤。
此外,使用 mapValues() 创建一个新字典,其中包含一个键和一个值,并将值转换为可选的双精度值。我不明白的是如何将所有 5 个值元素转换为双精度值,即拥有一个与从 JSON 文件中读取的相同但所有 5 个值都为双精度值或可选双精度值的字典。
下面是 JSON 文件和我的代码的 sn-p。如果您能指出我正确的方向,我们将不胜感激。
"Time Series (Daily)": {
"2021-09-22": {
"1. open": "402.1700",
"2. high": "405.8500",
"3. low": "401.2600",
"4. close": "403.9000",
"5. volume": "5979811"
},
"2021-09-21": {
"1. open": "402.6600",
"2. high": "403.9000",
"3. low": "399.4400",
"4. close": "400.0400",
"5. volume": "6418124"
},
struct Stock: Codable {
let timeSeriesDaily: [String : TimeSeriesDaily] // creates a dictionary, key = string : TimeSeriesDaily = value
enum CodingKeys: String, CodingKey {
case timeSeriesDaily = "Time Series (Daily)"
}
}
struct TimeSeriesDaily: Codable {
let Open, High, Low, Close: String
let Volume: String
enum CodingKeys: String, CodingKey {
case Open = "1. open"
case High = "2. high"
case Low = "3. low"
case Close = "4. close"
case Volume = "5. volume"
}
}
class ReadData: ObservableObject {
@Published var tmpData = Stock(timeSeriesDaily : [:]) // initialize dictionary as empty when struct Stock is created
// type info has to be made availabe upon creation, is done in the Stock struct
init() {
loadData()
}
func loadData() {
guard let url = Bundle.main.url(forResource: "VOO", withExtension: "json")
else {
print("Json file not found")
return
}
let decoder = JSONDecoder()
do {
let data = try Data(contentsOf: url)
self.tmpData = try decoder.decode(Stock.self, from: data)
// print(self.tmpData)
} catch {
print(error)
}
}
}
struct ContentView: View {
@ObservedObject var vooData = ReadData()
var body: some View {
ScrollView {
VStack (alignment: .leading) {
let lastYear = getOneYearAgo()
let filteredDict = vooData.tmpData.timeSeriesDaily.filter { $0.key > lastYear } // Works
let sortedFilteredDict = filteredDict.sorted { $0.key < $1.key } // Works
let justCloseArray = sortedFilteredDict.map { ($0.key, $0.value.Close) } // returns array [(String, String)]
let justCloseDict = Dictionary(uniqueKeysWithValues: justCloseArray) // returns dictionary with 1 key & 1 val
let sortedCloseDict = justCloseDict.sorted { $0.key < $1.key } // works
let newDict = filteredDict.mapValues { Double($0.Close) }
let sortedNewDict = newDict.sorted { $0.key < $1.key }
Spacer()
// ForEach ( sortedCloseDict.map { ($0.key, $0.value) }, id: \.0 ) { keyValuePair in
ForEach ( sortedNewDict.map { ($0.key, $0.value) }, id: \.0 ) { keyValuePair in // map converts dictionary to arrap
HStack {
Text (keyValuePair.0)
Text ("\(keyValuePair.1!)")
}
}
Spacer()
} // end vstack
} .frame(width: 600, height: 400, alignment: .center) // end scroll view
}
}
【问题讨论】:
标签: swift dictionary key-value