如何使用JSONDecoder解码时按order键自动排序FieldModel数组
嘿,这个需求很常见,我来给你捋捋怎么实现!要让JSONDecoder解析ContentModel时自动把content数组按order字段排序,有两种实用的方式,看你偏好哪种:
方法一:用计算属性快速实现
这种方式最简单,不用修改解码逻辑,只需要在模型里加一个对外暴露的计算属性,返回排序后的数组:
首先先定义基础的FieldModel:
struct FieldModel: Codable { let fieldName: String let label: String let order: Int }
然后改造ContentModel:
struct ContentModel: Codable { // 私有存储原始未排序的数组,解码时正常解析 private let content: [FieldModel] // 对外提供的已排序数组,按order升序排列 var sortedContent: [FieldModel] { content.sorted { $0.order < $1.order } } }
使用的时候直接访问sortedContent就能拿到排好序的字段数组,解码代码还是和之前一样:
let decodedModel = try JSONDecoder().decode(ContentModel.self, from: apiResponseData) let sortedFields = decodedModel.sortedContent
方法二:自定义解码逻辑(解码时直接排序)
如果你希望解码后拿到的content本身就是排好序的,不需要额外访问计算属性,可以自定义解码初始化器,在解码阶段就完成排序:
struct FieldModel: Codable { let fieldName: String let label: String let order: Int } struct ContentModel: Codable { let content: [FieldModel] // 自定义解码初始化方法 init(from decoder: Decoder) throws { // 获取解码容器 let container = try decoder.container(keyedBy: CodingKeys.self) // 先解码出原始的字段数组 var rawContent = try container.decode([FieldModel].self, forKey: .content) // 按order升序排序(如果需要降序就改成 >) rawContent.sort { $0.order < $1.order } // 把排序后的数组赋值给content self.content = rawContent } // 定义CodingKeys,确保和API返回的键名对应 enum CodingKeys: String, CodingKey { case content } }
这样解码后直接访问decodedModel.content就是已经按order排好序的数组了,完全符合你“解码时自动得到排序数组”的需求。
额外小提示
如果遇到多个字段order相同的情况,可以扩展排序逻辑,比如按fieldName或者label二次排序:
rawContent.sort { if $0.order == $1.order { // 相同order时按fieldName字典序排序 return $0.fieldName < $1.fieldName } else { return $0.order < $1.order } }
内容的提问来源于stack exchange,提问作者Jogendar Choudhary
相关产品推荐
相关产品推荐

