【问题标题】:Decoding nested JSON when the keys at the lowest level are the same当最低级别的键相同时解码嵌套的 JSON
【发布时间】:2021-04-04 02:13:57
【问题描述】:

我需要你的帮助来解码这段 JSON

{
    "json": {
        "firstItem": {
            "key": "key",
            "value": "data"
        },
        "secondItem": {
            "key": "key",
            "value": "data"
        },
        "thirdItem": {
            "key": "key",
            "value": "data"
        },.......... //All of the data, which is a lot, comes like this
    }
}

我希望能够解码这些数据,但由于项目很多,所以在不必编写太多代码的情况下无法找到方法。是否可以将此 JSON 解码为字典嵌套,或者甚至更好地解码为仅具有键和值属性的项目对象数组?提前致谢

【问题讨论】:

  • 尝试使用可编码的。

标签: ios json swift xcode dictionary


【解决方案1】:

如果您不知道嵌套 json 的键,您可以简单地将其解码为项目字典:

struct Root: Decodable {
    let json: [String: Item]
}

struct Item: Decodable {
    let key, value: String
}

let json = """
{
    "json": {
        "firstItem": {
            "key": "key",
            "value": "data"
        },
        "secondItem": {
            "key": "key",
            "value": "data"
        },
        "thirdItem": {
            "key": "key",
            "value": "data"
        }
    }
}
"""

do {
    let items = try JSONDecoder().decode(Root.self, from: .init(json.utf8)).json.map(\.value)
    print(items)
} catch {
    print(error)
}

这将打印:

[项目(键:“键”,值:“数据”),项目(键:“键”,值:“数据”),项目(键:“键”,值:“数据”)]

【讨论】:

    【解决方案2】:

    使用 Swifts 结构与 Codable 结合,我们可以实现非常干净和漂亮的问题解决方案。

    声明项目结构

    帮助结构在从 json 字典中包含的每个项目中检索值时很有用

    struct Item: Codable {
        let key: String
        let value: String
    }
    

    解码 JSON

    现在,考虑到 json 是一个字符串值,您可以使用 JSONDecoder 轻松解码它

    let jsonString: String // your json here
    
    guard let data = jsonString.data(using: .utf8) else { return }
    let decoder = JSONDecoder()
    do {
        let decoded = try decoder.decode([String: [String: Item]].self, from: data)
        let itemsDict: [String: Item] = decoded["json"] ?? [:]
    
        // do what you want with the items!
        let firstItem: Item? = itemsDict["firstItem"]
        let items: [Item] = itemsDict.values
    } catch {
        print(error)
    }
    

    【讨论】:

    • 太棒了,很高兴听到这个消息!
    【解决方案3】:

    为您的键/值对创建自定义类型

    struct KeyValue: Decodable {
        let key: String
        let value: String
    }
    

    然后将它们解码成这样的数组

    do {
        let result = try JSONDecoder().decode([String: [String: KeyValue]].self, from: data)
        let array = result["json"]?.reduce(into: []) { $0.append($1.value) }
    } catch {
        print(error)
    }
    

    【讨论】:

      【解决方案4】:

      我带着我的答案去了老学校:

      guard let json = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: [String: [String: Any]]] else { return }
      let keyValues = json["json"].map { $0.values.map { ($0["key"]! as! String, $0["value"]!) } }
      

      【讨论】:

        猜你喜欢
        • 2021-01-03
        • 2019-12-14
        • 2021-10-12
        • 1970-01-01
        • 2018-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-22
        相关资源
        最近更新 更多