如何使用 JSONDecoder 根据订单键获取排序数据?
Posted
技术标签:
【中文标题】如何使用 JSONDecoder 根据订单键获取排序数据?【英文标题】:How can i get sorted data according to order key using JSONDecoder? 【发布时间】:2018-04-28 12:40:55 【问题描述】:我正在从 API 获取响应并使用“JSONDecoder”解析响应并能够解析,但我想要根据“ContentModel”自动的“内容”对象中的“顺序”键排序的“FieldModel”数组我使用 JSONDecoder 解码?
我的 API 回复:
content = (
fieldName = \"$.alcohol.beer\";
label = Beer;
order = 2;
,
fieldName = \"$.alcohol.wine\";
label = Wine;
order = 1;
,
fieldName = \"$.alcohol.any\”;
label = Wine;
order = 3;
);
我的模型:
struct ContentModel: Codable
var content: [FieldModel]?
struct FieldModel: Codable
var fieldName: String?
var order: Int?
var label: String?
数据解码代码:
let myFinalData = try JSONDecoder().decode(ContentModel.self, from: jsonData)
如何获取 ContentModel 的内容在使用上述代码解码后按照 order key 排序?
【问题讨论】:
myFinalData.content = myFinalData.content.sorted ($0.order ?? 0) < ($1.order ?? 0)
。您拥有的所有选项都不会很好。
对不起,我不想使用手动排序方式,当使用 JSONDecoder 解析数据时,它将自动保存内容中的排序数据。我不想在解析后添加/使用任何行代码。在解析之前如何添加这个排序代码?
然后将其写入init(from: Decoder)
。
这不是 json
【参考方案1】:
您可以通过为您的ContentModel
结构创建自定义init(from decoder)
方法来实现您的目标,其中您使用FieldModel
元素的order
属性将FieldModel
s 分配到它们在content
数组。
我还建议您将结构的所有字段设为不可变且非可选,除非您有充分的理由不这样做。
struct ContentModel: Codable
let content: [FieldModel]
private enum CodingKeys: String, CodingKey
case content
init(from decoder:Decoder) throws
let container = try decoder.container(keyedBy: CodingKeys.self)
let content = try container.decode([FieldModel].self, forKey: .content)
var orderedContent = content
for element in content
orderedContent[element.order-1] = element
self.content = orderedContent
struct FieldModel: Codable
let fieldName: String
let label: String
let order: Int
【讨论】:
我不想对解决方案本身提出批评,但解码时排序——正如 OP 所期望的那样——比.sorted ...
line after 更昂贵(而且效率低下) 解码。以上是关于如何使用 JSONDecoder 根据订单键获取排序数据?的主要内容,如果未能解决你的问题,请参考以下文章
Swift 5:如何从 JSONDecoder().decode 获取数据?
如何准备 API 响应以在 swift 中与 jsonDecoder 一起使用
如何从 WooCommerce 中的订单项中获取产品类别 ID