John
John

Reputation: 1015

Issue decoding JSON | Swift

I am having an issue dynamically populating the date associated with each section. The value of grouped is currently derived from grouping the raw JSON data by routeid

You can see that I am currently using a static value for date as a test, while $0.key represent the value of myID dynamically.

How can also add the dynamic value of myDate intead of "test"?

Variables:

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

Currently this is true

sections.map(\.id) == [8,4]

At the end this must be true as well

sections.map(\.date) == [2021-01-20, 2021-01-18]

Decoding:

do {
      let decoder = JSONDecoder()
      let res = try decoder.decode([myStructure].self, from: data)
      let grouped = Dictionary(grouping: res, by: { $0.myID })
      _ = grouped.keys.sorted()
      sections = grouped.map { mySections(date: "test", id: $0.key, items: $0.value) }
      .sorted { $0.id > $1.id }
}

Struct:

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

struct myStructure: Decodable {
    let name: String
    let type: String
    let myID: Int
    let myDate: String
}

Example JSON:

[
  {
    "name": "Jeff",
    "type": "large",
    "myID": 8,
    "myDate": "2021-01-20"
  },
  {
    "name": "Jessica",
    "type": "small",
    "myID": 4,
    "myDate": "2021-01-18"
  },
  {
    "name": "Beth",
    "type": "medium",
    "myID": 4,
    "myDate": "2021-01-18"
  }
]

Upvotes: 2

Views: 76

Answers (1)

Rob
Rob

Reputation: 437372

So, you want it grouped by both id number and date string? I would create a Hashable structure for those two values.

struct Section {
    let date: String
    let id: Int
    var items: [Item]
}

extension Section {
    struct Header: Hashable {
        let date: String
        let id: Int
    }
}

struct Item: Decodable {
    let name: String
    let type: String
    let myID: Int
    let myDate: String
}

And

let decoder = JSONDecoder()
let res = try decoder.decode([Item].self, from: data)
let sections = Dictionary(grouping: res) { Section.Header(date: $0.myDate, id: $0.myID) }
    .sorted { $0.key.id > $1.key.id }
    .map { Section(date: $0.key.date, id: $0.key.id, items: $0.value) }

Upvotes: 1

Related Questions