如何在结构类型的结构中单元化变量

How do I unitize a variable in structure that is of type structure

我一直在阅读 JSON 文件。在帮助下,我已经能够这样做,但现在想扩展我从 JSON 文件中读取的内容。我想我已经正确设置了结构,但是当我从 ReadData class 创建结构的实例时,不明白如何初始化 Stock 结构中的元数据变量。我已经将 ? 放在 ReadData 中给我带来问题的代码行中 任何帮助,将不胜感激。 克里斯 下面是 JSON 数据和我的代码。

"Meta Data": {
    "1. Information": "Daily Prices (open, high, low, close) and Volumes",
    "2. Symbol": "VOO",
    "3. Last Refreshed": "2021-09-22",
    "4. Output Size": "Full size",
    "5. Time Zone": "US/Eastern"
},
"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"
    },

struct Stock: Codable {
    let metaData: MetaData
    let timeSeriesDaily: [String : TimeSeriesDaily]  // creates a dictionary, key = string : TimeSeriesDaily = value
    enum CodingKeys: String, CodingKey {
        case metaData = "Meta Data"
        case timeSeriesDaily = "Time Series (Daily)"
    }
}
struct MetaData: Codable {
    let Information : String
    let Symbol : String
    let LastRefreshed : String
    let OutputSize : String
    let TimeZone: String
    enum CodingKeys: String, CodingKey {
        case Information = "1. Information"
        case Symbol = "2. Symbol"
        case LastRefreshed = "3. Last Refreshed"
        case OutputSize = "4. Output Size"
        case TimeZone = "5. Time Zone"
    }
}
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(metaData: ????? , timeSeriesDaily : [:])
    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 { [=10=].key > lastYear } // Works
//                let sortedFilteredDict = filteredDict.sorted { [=10=].key < .key }                 // Works
//                let justCloseArray = sortedFilteredDict.map { ([=10=].key, [=10=].value.Close) }           // returns array [(String, String)]
//                let justCloseDict = Dictionary(uniqueKeysWithValues: justCloseArray)                // returns dictionary with 1 key & 1 val
//                let sortedCloseDict = justCloseDict.sorted { [=10=].key < .key }                      // works
                let newDict = filteredDict.mapValues { Double([=10=].Close) }
                let sortedNewDict = newDict.sorted { [=10=].key < .key }
                Spacer()
                //                ForEach ( sortedCloseDict.map { ([=10=].key, [=10=].value) }, id: \.0 ) { keyValuePair in
                ForEach ( sortedNewDict.map { ([=10=].key, [=10=].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
    }
}

您需要向其传递一个 MetaData 结构。 MetaData 的初始值设定项需要一些匹配其属性的 Strings

@Published var tmpData = Stock(metaData: MetaData(Information: "", Symbol: "", LastRefreshed: "", OutputSize: "", TimeZone: ""), timeSeriesDaily: [:])

一个提示是 Xcode 会自动为您完成其中的大部分内容。如果您开始输入 Stock 并让自动完成完成工作,您会看到它为 metaDatatimeSeriesDaily 参数生成模板。