首页 > 解决方案 > 无键容器的 JSON 数组(快速解析)

问题描述

我该如何解析这个?数组未命名,对象未命名?我还需要对其进行排序并找到事件之间的重叠如果你们也有任何建议,这对我来说将是一个巨大的帮助。

[{"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"}]    

我是 swift 新手,我想知道如何处理这个问题

标签: jsonswiftsortingdateparsing

解决方案


您的 JSON 不需要您实现无键容器来解析它的无键容器示例。您需要的是自定义DateFormatterDateDecodingStrategy. 要对事件进行排序,您需要使其符合Comparable协议

DateFormatter假设您的日期字符串是具有本地时间的固定日期格式:

extension Formatter {
    static let custom: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "MMMM d, yyyy h:mm a"
        return formatter
    }()
}

习俗DateDecodingStrategy

extension JSONDecoder.DateDecodingStrategy {
    static let monthDayYearTime = custom {
        let container = try $0.singleValueContainer()
        let string = try container.decode(String.self)
        guard let date = Formatter.custom.date(from: string) else {
            throw DecodingError.dataCorruptedError(in: container,
                  debugDescription: "Invalid date: " + string)
        }
        return date
    }
}

您的Codable活动结构:

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

使其符合Comparable协议

extension Event: Comparable {
    static func < (lhs: Event, rhs: Event) -> Bool { lhs.start < rhs.start }
}

一个习惯description

extension Event: CustomStringConvertible {
    var description: String {
        "Title: \(title) - Start: \(Formatter.custom.string(from: start)) - End: \(Formatter.custom.string(from: end))"
    }
}

游乐场测试:

您的 JSON 字符串:

let json = """
[{"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"}]
"""

解码你的 JSON

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .monthDayYearTime
do {
    let events = try decoder.decode([Event].self, from: Data(json.utf8))
    print(events.sorted())
} catch {
    print(error)
}

这将打印

[标题:足球比赛 - 开始:2018 年 11 月 3 日下午 6:14 - 结束:2018 年 11 月 3 日晚上 9:44,标题:午睡 - 开始:2018 年 11 月 8 日下午 12:56 - 结束:2018 年 11 月 8 日下午 1:30,标题:晚上野餐 - 开始:2018 年 11 月 10 日下午 6:00 - 结束:2018 年 11 月 10 日晚上 7:00]


推荐阅读