Home > front end >  Trying to get the first element of JSON array Swift
Trying to get the first element of JSON array Swift

Time:09-26

I'm trying to implement a stock API. I have a JSON example:

{
"Meta Data": {
    "1. Information": "Daily Prices (open, high, low, close) and Volumes",
    "2. Symbol": "DAI.DEX",
    "3. Last Refreshed": "2022-04-05",
    "4. Output Size": "Full size",
    "5. Time Zone": "US/Eastern"
},
"Time Series (Daily)": {
    "2022-04-05": {
        "1. open": "64.4900",
        "2. high": "64.8200",
        "3. low": "62.6200",
        "4. close": "62.9600",
        "5. volume": "3425810"
    },
    "2022-04-04": {
        "1. open": "63.9900",
        "2. high": "64.5400",
        "3. low": "62.8100",
        "4. close": "64.2600",
        "5. volume": "2538008"
    }
}

I'm trying to display the latest price so I always need the first element in Time Series Daily. In this example 2022-04-05. The list goes on for 20 years. I tried this:

var latestClose: String {
    timeSeriesDaily.first?.value.close ?? ""
}

But every time I rerun the app it displays different values and not constantly the first value.

Here my Code:

struct StockData: Codable {

     var metaData: MetaData
     var timeSeriesDaily: [String: TimeSeriesDaily]

     var latestClose: String {
         timeSeriesDaily.first?.value.close ?? ""
     }

     private 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
    
         private 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 {
         var open: String
         var high: String
         var low: String
         var close: String
         var volume: String
    
         private enum CodingKeys: String, CodingKey {
             case open = "1. open"
             case high = "2. high"
             case low = "3. low"
             case close = "4. close"
             case volume = "5. volume"
         }
     }
 }

CodePudding user response:

There is no first element because the object is a dictionary which is unordered by definition.

To get the most recent item you have to get the dictionary keys (this returns an array) and sort them descending. The most recent date is the first item.

 var latestClose: String {
     guard let mostRecentDate = timeSeriesDaily.keys.sorted(by: >).first else { return "" }
     return timeSeriesDaily[mostRecentDate]!.close
 }
  • Related