Home > other >  Filtering dictionaries within array with JSON decoding based on latest date in Swift
Filtering dictionaries within array with JSON decoding based on latest date in Swift

Time:09-29

I have a JSON file which I pull from an API. I am able to decode the correct parts of the JSON that I need but I need to filter the last part based on the latest date and another criteria.

So the part of the JSON that I need to parse looks like this:

"tables": {
        "calendars": [{
            "event_id": "GH162",
            "begin_date_time": "2013-01-24",
            "end_date_time": "2013-01-24",
            "event_type": 201,
            "estimated_date_for_next_event": "1970-01-01"
        }, {
            "event_id": "GH182",
            "begin_date_time": "2015-01-30",
            "end_date_time": "2015-01-30",
            "event_type": 205,
            "estimated_date_for_next_event": "1970-01-01",
        },

This calendar section has around 100 dictionaries. I need to find the one where the end_date_time is the latest and for a certain event_type.

struct EventCalendar: Codable {
let eventID: String
let beginDateTime: String
let endDateTime: Date
let eventType: Int
let estimatedDateForNextEvent: String

enum CodingKeys: String, CodingKey {
    case eventID = "event_id"
    case beginDateTime = "begin_date_time"
    case endDateTime = "end_date_time"
    case eventType = "event_type"
    case estimatedDateForNextEvent = "estimated_date_for_next_event"
} }

In the struct that appoints types to all the elements within the JSON I put begin_date_time as a string and end_date_time as a date type. The reason is that I think date output is international standard and I understood it wasnt always necessary to convert this to date in order to find the latest one. So played around with both dates since they are the same.

The code I use the parse this part(The decoding part all happenes before and I pass the part of the JSON that I need into this function):

func parseArray(data: [EventCalendar]) {
    let calendarData = data.first(where:{$0.eventType == 201})
    //let calendarData = data.max(by: <#T##(EventCalendar, EventCalendar) throws -> Bool#>)
    print(calendarData)
               //no userdata

    }

The first(where: works fine and I am able to get back the correct dictionary that contains the element I filtered for, see code below. However, I also need to filter the date.

Optional(Event_Alert.EventCalendar(EventID: "GH162", beginDateTime: "2013-01-24", endDateTime: 2013-01-23 23:00:00  0000, eventType: 201, estimatedDateForNextEvent: "1970-01-01"))

I tried using the .max(by: function but this did not work or I didnt fill it in correctly. What I need is to find the dictionary within the array with a specific eventType and which is the the most recent(so with the latest date) Anyone any idea what could work?

CodePudding user response:

I’d suggest to filter and then sort the array descending by the end date so the first item in the result is the latest entry. As first is an optional unwrap it safely

if let latestEntry = data.filter{$0.eventType == 201}
                         .sorted{$0.endDateTime > $1.endDateTime}
                         .first { 
  • Related