parse JSON array in swift , sort it and find overlapping dates

五迷三道 提交于 2020-02-25 05:56:10

问题


How do I parse this? The array is unnamed, the objects are unnamed? I also need to sort it and find overlaps(identify conflicts) between events IF you guys have any advice there too it will be a huge help for me.

[{"title": "Evening Picnic", "start": "November 10, 2018 6:00 PM", "end": "November 10, 2018 7:00 PM"}, {"title": "Nap Break", "start": "November 8, 2018 12:56 PM", "end": "November 8, 2018 1:30 PM"}, {"title": "Football Game", "start": "November 3, 2018 6:14 PM", "end": "November 3, 2018 9:44 PM"}, {"title": "Evening Cookout with Friends", "start": "November 6, 2018 5:00 PM", "end": "November 6, 2018 10:00 PM"}, {"title": "Roller Derby", "start": "November 7, 2018 12:00 PM", "end": "November 7, 2018 2:30 PM"}, {"title": "Basketball Game", "start": "November 8, 2018 7:30 PM", "end": "November 8, 2018 10:30 PM"}, {"title": "Local Pub with Friends", "start": "November 1, 2018 7:33 PM", "end": "November 1, 2018 11:00 PM"}, {"title": "Dentist Appointment", "start": "November 10, 2018 1:45 PM", "end": "November 10, 2018 2:30 PM"}, {"title": "Volleyball With Friends", "start": "November 6, 2018 12:00 PM", "end": "November 6, 2018 1:26 PM"}, {"title": "Free Donuts", "start": "November 9, 2018 3:00 PM", "end": "November 9, 2018 4:00 PM"}, {"title": "TV Show Marathon", "start": "November 9, 2018 4:30 PM", "end": "November 9, 2018 9:00 PM"}, {"title": "Boba Tea Grand Opening", "start": "November 6, 2018 1:27 PM", "end": "November 6, 2018 2:00 PM"}, {"title": "Lunch with Friends", "start": "November 8, 2018 11:30 AM", "end": "November 8, 2018 12:59 PM"}, {"title": "SF Coffee Festival","start": "November 6, 2018 6:00 PM","end": "November 6, 2018 9:00 PM"}, {"title": "Beer with Friends", "start": "November 9, 2018 8:00 PM", "end": "November 9, 2018 9:30 PM"}, {"title": "Yoga", "start": "November 1, 2018 6:00 PM", "end": "November 1, 2018 7:33 PM"}, {"title": "Rock Concert", "start": "November 7, 2018 6:30 PM", "end": "November 7, 2018 11:00 PM"}, {"title": "Lunch Meeting", "start": "November 9, 2018 12:30 PM", "end": "November 9, 2018 2:30 PM"}, {"title": "Bicycling with Friends", "start": "November 1, 2018 6:00 AM", "end": "November 1, 2018 9:30 AM"}, {"title": "Birthday Party", "start": "November 10, 2018 12:30 PM", "end": "November 10, 2018 8:30 PM"}, {"title": "Football Tailgate with John", "start": "November 3, 2018 6:14 PM", "end": "November 3, 2018 9:44 PM"}]   

I'm new to swift and I'm wondering how to deal with this


回答1:


Considering this is a follow up question from your previous post. You can use Swift DateInterval initialiser to create a DateInverval with your start and end dates and check if they intersects with each other:

extension Event {
    var interval: DateInterval { .init(start: start, end: end) }
    func intersects(with event: Event) -> Bool { interval.intersects(event.interval) }
}

To check for conflicting events you would need to make your Event conform to Equatable and filter the ones that intersects with them but are not the same event:

struct Event: Codable, Equatable {
    let title: String
    let start: Date
    let end: Date
}

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .monthDayYearTime
do {
    let events = try decoder.decode([Event].self, from: Data(json.utf8))
    print(events.sorted())
    let conflictingEvents: [(Event, Event)] = events.compactMap {
        for event in events where event != $0 {
            if event.intersects(with: $0) && $0.end != event.start && event.end != $0.start { return ($0, event) }
        }
        return nil
    }
    print(events.count)             // "21\n"
    print(conflictingEvents.count)  // "11\n"
} catch {
    print(error)
}



回答2:


There are only two "difficult" things with your JSON structure which might make it throw a spanner in the works.

The fact that's it a straight up JSON array and the non-standard date format.

I would recommend starting with a good tutorial, something like Ultimate Guide to JSON Parsing with Swift, which is may de-facto source, as it covers almost all the use-cases I've had to date.

Start by defining a construct to hold the basic data and conform to the Codable protocol

struct Event: Codable {
    let title: String
    let end: Date
    let start: Date
}

Create a JSONDecoder and provide it with a custom dateDecodingStrategy

let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd, yyyy hh:mm a"

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)

You need to convert you JSON response to Data. I might already be in this format or you can convert the String text directly, which I did for my testing

let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd, yyyy hh:mm a"
formatter.locale = Locale(identifier: "en_US_POSIX")

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)

Finally, decode the response...

let events = try decoder.decode([Event].self, from: data)

From there you can start processing the data.

Sorting a array and date comparison is such a readily asked question, there are just simply so many examples to choose from, I'm not going to try and repeat it here. Do some research, try some ideas. If you're still having issues, as another (focused) question and provide your attempts



来源:https://stackoverflow.com/questions/60142054/parse-json-array-in-swift-sort-it-and-find-overlapping-dates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!