问题
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