json - 在 Swift 4 中访问嵌套 JSON 字符串的成员

标签 json swift struct nested

我正在尝试解析嵌套的 JSON 字符串。下面是 JSON 字符串、我创建的结构以及我正在使用的 JSON 解码函数。我可以轻松访问名称成员,但在使用其他项目时遇到问题。例如,在我的 employeeData 对象中,如何从 2018 年 3 月 31 日的记录中访问 Sam 的工作时间?

提前谢谢你。

JSON 字符串

[
   {
      "name": "John",
      "records": [
         {
            "reportDate": "2018-06-30",
            "hours": 204,
            "billable": 32844
         },
         {
            "reportDate": "2018-03-31",
            "hours": 234,
            "billable": 37715
         }
      ]
   },
   {
      "name": "Sam",
      "records": [
         {
            "reportDate": "2018-06-30",
            "hours": 187,
            "billable": 13883
         },
         {
            "reportDate": "2018-03-31",
            "hours": 176,
            "billable": 13467
         }
      ]
   }
]

结构

struct Employee : Decodable {

let name : String?
let records : [Record]

private enum CodingKeys: String, CodingKey {
    case name = "name"
    case records
}

struct Record : Decodable {

    let reportDate : String?
    let hours : Int?
    let billable : Int?

    private enum CodingKeys: String, CodingKey {
        case reportDate = "reportDate"
        case hours = "hours"
        case billable = "billable"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        reportDate = try values.decodeIfPresent(String.self, forKey: .reportDate)
        hours = try values.decodeIfPresent(Int.self, forKey: .hours)
        billable = try values.decodeIfPresent(Int.self, forKey: .billable)
    }
}
}

JSON解码小说

func downloadJSON( completed:@escaping ()->()){

guard let qurl = URL("https://website.com") else { return }
URLSession.shared.dataTask(with: qurl) { (data, response, error) in
    if error == nil {
        do{
            self.employeeData = try JSONDecoder().decode([Employee].self, from: data!)

            DispatchQueue.main.async{ completed() }
        } catch { print("JSON Error") }
    }
    }.resume()
}

最佳答案

首先你可以减少你的结构

struct Employee : Decodable {

    let name : String
    let records : [Record]

    struct Record : Decodable {

        let reportDate : String
        let hours : Int
        let billable : Int
    }
}

CodingKeys 和初始化器由协议(protocol)扩展创建。

要获取内部数据你需要两个循环

for employee in self.employeeData {
    print(employee.name)
    for record in employee.records {
        print(record.reportDate)
        print(record.hours)
    }
}

要获取 Sam 在 2018-03-31 的工作时间,您可以使用

过滤数据
if let sam = self.employeeData.first(where: {$0.name == "Sam"}),
    let date = sam.records.first(where: {$0.reportDate == "2018-03-31"}) {
    print(date.hours)
}

关于json - 在 Swift 4 中访问嵌套 JSON 字符串的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51691329/

相关文章:

xcode - 在 Xcode (Swift) 中查看 NSData 内容

swift - 如何使枚举符合 Swift 中的协议(protocol)?

struct - 如何将一个结构向量映射或转换为另一个结构向量?

c - 如何在C中的结构中打印字符串

c - 为什么它在通过引用传递时只加 2?

javascript - 为什么以及何时我们需要展平 JSON 对象?

android - 通过gson解析json返回null

python - 迭代 Pandas 分组数据框

swift - NSLayoutConstraint withVisualFormat布局

json - 当我想存储 UTC 日期时间时,如何停止 Entity Framework 转换 Json UTC 日期时间