1

How can I sort the following sections made dynamically from the datestamp field? For example the sections called 2021-11-3 needs to be displayed in the tableview above 2021-11-2

datestamp format: 2021-11-3

var sections = [mySections]()
var structure = [myStructure]()

private func fetchJSON() {
    
    guard let url = URL(string: "test.com")
    else { return }
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = "id=\1".data(using: .utf8)
    

URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data else { return }
                
do {
  let decoder = JSONDecoder()
  self.structure.sort { $0. datestamp > $1.datestamp }
  let res = try decoder.decode([myStructure].self, from: data)
  let grouped = Dictionary(grouping: res, by: { $0. datestamp })
  let keys = grouped.keys.sorted()
self.sections = keys.map({mySections(date: $0, items: grouped[$0]!
                    
)})
  DispatchQueue.main.async {
  self.tableView.reloadData()
}
        }
        
        catch {
            print(error)
        }
    }.resume()
 }

I have tried doing the following under self.sections but it does not do anything:

self.sections.sorted { $0.date > $1.date }

Struct:

struct mySections {
    let date : String
    var items : [myStructure]
}


struct myStructure: Decodable {
    
    let recordid: Int
    let testname: Int
    let datestamp: String
}

Example of Data:

[
  { 
    "recordid": 1,
    "testname": "Jen",
    "datestamp": "2021-11-3"
  },
  {
    "recordid": 1,
    "testname": "Jake",
    "datestamp": "2021-11-2"
  }
]
John
  • 965
  • 8
  • 16
  • It's not clear if the `date` field of `mySections` is accurately set -- you haven't included `routeSections`. Can you provide your JSON & the remaining code necessary to make this a [mre]? – jnpdx Nov 03 '21 at 18:43
  • Please see the updated post – John Nov 03 '21 at 19:12
  • Thank you for your help - can you please take a look at this other post, I appreciate your help. https://stackoverflow.com/questions/69860143/how-to-identify-first-and-last-rows-of-each-section-swift – John Nov 05 '21 at 23:13

1 Answers1

0

Right now, you're sorting structure based on dateTimeStamp, which doesn't do anything, because structure doesn't have any data in it.

In my playground example, like your code, I used Dictionary(grouped:). Then, I map those results to mySections and sort by date.

The result of the print at the end is:

["2021-11-4", "2021-11-3", "2021-11-2"]

let data = """
[
  {
    "recordid": 1,
    "testname": "Jake",
    "datestamp": "2021-11-2"
  },
  {
    "recordid": 2,
    "testname": "Jen",
    "datestamp": "2021-11-3"
  },
      {
        "recordid": 3,
        "testname": "Bob",
        "datestamp": "2021-11-3"
      },
      {
        "recordid": 4,
        "testname": "Bill",
        "datestamp": "2021-11-4"
      }
]
""".data(using: .utf8)!

struct mySections {
    let date : String
    var items : [myStructure]
}


struct myStructure: Decodable {
    let recordid: Int
    let testname: String
    let datestamp: String
}

var sections = [mySections]()
var structure = [myStructure]()

do {
    let decoder = JSONDecoder()
    let res = try decoder.decode([myStructure].self, from: data)
    let grouped = Dictionary(grouping: res, by: { $0.datestamp })
    sections = grouped.map { mySections(date: $0.key, items: $0.value) }
        .sorted { $0.date > $1.date }
    print(sections.map(\.date))
} catch {
    print(error)
}

It's probably worth noting that right now your dates are stored in a uniform format that works well for string-based sorting. However, if your endpoint returned dates that weren't uniformly-formatted (like 2021-11-04 and 2021-11-3) you would want to convert to an actual Date first and sort based on that.

jnpdx
  • 45,847
  • 6
  • 64
  • 94