【问题标题】:Swift json decoding loses json object key orderSwift json解码丢失json对象键顺序
【发布时间】:2018-02-27 00:09:06
【问题描述】:

我有一个简单的 JSON 对象:

{
    "values": {
        "a":"",
        "b":"",
        "c":"",
        "d":"",
        "e":""
    }
}

我想以这样的方式将它解码为 Swift 结构,以后我可以以与收到 JSON 对象完全相同的顺序迭代 values 中的键.

这在 Swift 中可行吗?


我的尝试如下:

let json = "{ \"values\": { \"a\":\"\", \"b\":\"\", \"c\":\"\", \"d\":\"\", \"e\":\"\" } }"

struct JSS: Codable {
    var values: [String: String?]?
}

let data = json.data(using: .utf8)

do {
    let decoder = JSONDecoder()
    let jss = try decoder.decode(JSS.self, from: data!)
    jss.values?.map { print("\($0.key)") }
}
catch {
}

将打印:

b
e
a
d
c

【问题讨论】:

  • JSON 字典按照定义是无序的,Swift 字典也是如此。根据 JSON 标准,在对 JSON 进行编码/解码时,不需要保留 Dictionary 内的顺序,因此您看到的是预期的行为。
  • 如果您需要按字母顺序迭代您的键,只需按其键对已解析的字典进行排序。我认为不可能得到与它相同的订单。
  • 顺便说一句,您可以使用三重双引号来更轻松地表示您的 JSON 字符串,而无需转义特殊字符 let json = """ { "values": { "a":"", "b":"", "c":"", "d":"", "e":"" } } """

标签: json swift


【解决方案1】:

这不是 Swift 本身的限制。 Swift 和 JSON 字典都是无序的。 JSON 格式不保证键顺序,因此不需要解析器保留顺序。

如果您需要一个有序集合,最好在 JSON 中返回一个键值对数组:

{
    "values": [
        {"a" : ""},
        {"b" : ""},
        {"c" : ""},
        {"d" : ""},
        {"e" : ""}
    ]
}

然后以正确的顺序存储密钥,以便能够根据需要对其进行迭代。

【讨论】:

  • 好答案。 (已投票。)不幸的是,许多 JSON 解析器确实保留了列表中键/值对的顺序,因此开发人员编程依赖它,尽管正如您所说,它不能保证。跨度>
  • 请注意,在编码 JSON 编码器时,您可以让键按字典顺序排序。
【解决方案2】:

以下方法不起作用所以您不要浪费时间尝试:

回到旧的时尚方式,使用JSONSerialization.jsonObject(with: Data, options: JSONSerialization.ReadingOptions) -> Any

它确实保持秩序.....直到您将json?["values"] 转换为[String: Any]。这时Cezar在上面answer所说的进入场景:字典是无序的。

以下屏幕截图显示,在json?["values"]Any 之前,顺序保留在字符串描述中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多