从 JSON 解码 KeyValuePairs<String: Person>

Posted

技术标签:

【中文标题】从 JSON 解码 KeyValuePairs<String: Person>【英文标题】:Decode KeyValuePairs<String: Person> from JSON 【发布时间】:2020-06-05 15:21:10 【问题描述】:

我有一个如下所示的 JSON 响应:

 
    "persons": 
        "John": 
            "name": "John",
            "age": 24
        ,
        "Michael": 
            "name": "Michael",
            "age": 44
        ,
        "Jack": 
            "name": "Jack",
            "age": 25
        
    

如您所见,这可以使用如下所示的结构进行解析:

struct PersonsResponse: Decodable 
    let persons: [String: Person]


struct Person: Decodable 
    let name: String
    let age: Ing

但是,它的作用是返回一个字典并很好地解析。我需要的是在人员到达此 JSON 响应时保留他们的顺序。我在 swift 中遇到了KeyValuePairs,它们基本上是有序字典,但看在上帝的份上,我不知道如何将其解码为KeyValuePairs&lt;String, Person&gt;

Apple 文档说实例化 KeyValuePairs 对象就像做一样简单:

let recordTimes: KeyValuePairs = ["Florence Griffith-Joyner": 10.49,
                                      "Evelyn Ashford": 10.76,
                                      "Evelyn Ashford": 10.79,
                                      "Marlies Gohr": 10.81]

字面意思。但是当我解码我的回复时:

struct PersonsResponse: Decodable 
    let persons: KeyValuePairs<String, Person>
    ...
    ...

    init(from decoder: Decoder) throws 
    ...
    let personsDictionary = try container.decode([String: Person].self, forKey: .persons)

然后尝试做:

    persons = personsDictionary

当然,它根本不起作用。我已经尝试过各种魔法,但没有运气。有没有人有任何解决方案将字典解析为有序序列甚至数组?感谢您的帮助!

JSON 响应不可能变成一个数组,是的,它总是相同的顺序。

【问题讨论】:

KeyValuePairsCodingKeys 完全无关。字典是一种无序的集合类型。您确定 JSON 中的字典总是以相同的顺序发送吗?如果您负责后端,请发送一个数组。 这不能回答你的问题,但如果你有能力改变 JSON 格式,你应该这样做。如果您有两个同名的人,您将无法将两者都包含在结果中。 这不是完全重复的,但根本问题是相同的,答案是相同的。你不可以做这个。 ***.com/questions/16081104/… JSONDecoder 当前将所有数据放入一个 NSDictionary 然后解析出来(因为 JSONDecoder 目前是在 NSJSONSerialization 之上实现的)。那一步失去了秩序。您无法使用 JSONDecoder 解决此问题(而且我不知道 Swift 中有任何现成的 JSON 解析器可以)。 【参考方案1】:

Swift 和 JSON 字典本质上都是 unordered。 JSON 格式不维护键顺序,因此不需要解析器来保留顺序。

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

 
    "persons": [
         "John": 
            "name": "John",
            "age": 24
          
        ,
        "Michael": 
            "name": "Michael",
            "age": 44
          
        ,
        "Jack": 
            "name": "Jack",
            "age": 25
         
       
    ]

【讨论】:

目前还不清楚为什么这被否决了。这是完整的答案。 JSON 字典没有顺序,也不能像使用标准工具在 Swift 中一样被解码(你必须从头开始构建一些东西)。 我只是删除外部名称。你有一个字典数组,每个字典都包含一个字典。您不妨将所有字典放入一个数组中。 @RobNapier 但这不是答案所说的。它说“让服务器发出不同的东西”。没有答案。 我无法更改响应。只需要解析它

以上是关于从 JSON 解码 KeyValuePairs<String: Person>的主要内容,如果未能解决你的问题,请参考以下文章

Parallel.ForEach 具有可枚举的 KeyValuePairs?

Json 解码 Sharedpreferences 返回 List<dynamic> 而不是 List<Contact>

如何将 List<KeyValuePairs<int,object>> 保存为 SQLite 表?

如何使用 JSON 输入字符串从编排中调用 JSON 解码器?

从 JSON 解码为自定义对象

从 api SwiftUI 解码 JSON 文件