我有 2 个JSON
对象正在使用。
第一个JSON
对象表示内容文章的数组。
[
{
"score":0.0,
"id":"508b860c-0134-47ef-81ea-6337f6be7845",
"fields":{
"summary":{
"id":"2c20b530-81e9-48ab-8507-b0388289e156",
"fieldType":"ENTRY"
},
"mainImage":{
"id":"acf96f3c-5824-4f9a-a1ed-b6a994bc25a4",
"fieldType":"ASSET"
}
},
"status":"PUBLISHED"
},
{
"score":0.0,
"id":"05fcd9cb-c055-4728-a244-ec91d1145200",
"fields":{
"summary":{
"id":"b1912a52-0a1c-42df-9eac-15a586feae8b",
"fieldType":"ENTRY"
},
"mainImage":{
"id":"129a4792-b0e4-46e3-ab6c-3801d292c378",
"fieldType":"ASSET"
}
},
"status":"PUBLISHED"
},
{
"score":0.0,
"id":"8e8f4731-a8dc-4936-bea5-e33c8e63256a",
"fields":{
"summary":{
"id":"886ea061-79fb-4364-b147-7f1f542a672d",
"fieldType":"ENTRY"
},
"mainImage":{
"id":"81bc9e4f-12c1-4ee1-bb11-a5dce883b23f",
"fieldType":"ASSET"
}
},
"status":"PUBLISHED"
}
]
数组中的每个项都包含一个表示内容项目的id
属性。然后,每个文章对象都有一个子对象,该对象列出了该文章的资产,每个资产都有一个唯一的id
。
我必须遍历每篇文章,并以ASSET
fieldType
提取资产。
然后,我向该资产主体的不同终结点发出网络请求。
这些请求中的每一个都返回一个响应,如下所示 -
请注意,这是使用id
prop 的三个请求,而不是单个请求中的数组。
{
"id":"acf96f3c-5824-4f9a-a1ed-b6a994bc25a4",
"createdAt":"2019-11-06T17:21:40Z",
"space":"main",
"contentType":"image/png",
"fileName":"cf43c65d-1a37-48ff-a0db-47e84be3a554.png",
"storageUri":"http://first-article-asset-id"
}
{
"id":"129a4792-b0e4-46e3-ab6c-3801d292c378",
"createdAt":"2019-11-06T17:21:40Z",
"space":"main",
"contentType":"image/png",
"fileName":"cf43c65d-1a37-48ff-a0db-47e84be3a554.png",
"storageUri":"http://second-article-asset-id"
}
{
"id":"81bc9e4f-12c1-4ee1-bb11-a5dce883b23f",
"createdAt":"2019-11-06T17:21:40Z",
"space":"main",
"contentType":"image/png",
"fileName":"cf43c65d-1a37-48ff-a0db-47e84be3a554.png",
"storageUri":"http://third-article-asset-id"
}
然后,我需要将此响应与第一个响应的文章 Id 进行匹配,方法是将fields
子对象上的 id 属性与上述响应的 id 属性进行匹配。
我想以一系列类似的东西结束——
struct MatchedAsset {
let articleId: String // eg: this would be 508b860c-0134-47ef-81ea-6337f6be7845"
let asset: ArticleAsset // eg: this would be the result of fetching acf96f3c-5824-4f9a-a1ed-b6a994bc25a4
}
我在这里对响应进行了建模 -
struct Article: Codable {
let id: String
let score: Int
let status: String
let fields: [String: ArticleAsset]
}
enum FieldType: String, Codable {
case asset = "ASSET"
case entry = "ENTRY"
}
struct ArticleAsset: Codable {
let fieldType: FieldType
let id: String
}
struct AssetContent: Codable {
let contentType: String
let createdAt: String
let fileName: String
let id: String
let space: String
let storageUri: String
}
我能够达到我在 2 个[Article]
数组和[AssetContent]
数组中同时拥有文章和资产请求响应的地步,但完全不知道如何使用这些集合。
到目前为止,任何尝试都是令人难以置信的循环,有大量嵌套map
、filter
和forEach
循环,似乎不起作用。
这是合并两个数组的解决方案,
var articles = [Article]()
var assets = [AssetContent]()
var merged = [Article]()
articles.forEach { article in
if let asset = article.fields.values.first(where: { $0.fieldType == .asset }) {
var updated = article
updated.asset = assets.first(where: {$0.id == asset.id})
merged.append(updated)
} else {
merged.append(article)
}
}
此解决方案将资产内容添加到文章中,因此您需要在文章中添加新属性
struct Article: Codable {
let id: String
let score: Int
let status: String
var asset: AssetContent?
let fields: [String: ArticleAsset]
}
当然,你可以有任何结构作为合并的输出,就像一个全新的结构,但在这里我试图让它尽可能简单