我收到来自服务器的响应,如下所示。在这里,review
和rating
在单独的对象中,booking_id相同。
{
"status": "Success",
"records": [
{
"user_name": "123user",
"review": "Ggg",
"booking_id": "Booking_23749",
"review_id": "review_38405",
"status": "active"
},
{
"_id": "5e0c43ea5bd0377f4cfdfa19",
"user_name": "123user",
"rating": 5,
"booking_id": "Booking_23749"
}
]
}
然后,我创建了一个Modal结构来存储来自服务器的数据。
struct ReviewRecord: Codable, Equatable {
static func == (lhs: ReviewRecord, rhs: ReviewRecord) -> Bool {
return lhs.bookingID == rhs.bookingID
}
let userName, review, bookingID, reviewID: String?
let status, id: String?
let rating: Int?
enum CodingKeys: String, CodingKey {
case userName = "user_name"
case review
case bookingID = "booking_id"
case reviewID = "review_id"
case status
case id = "_id"
case rating
}
}
我用它作为
var reviewsData = [ReviewRecord]() // appending all data received in reviewsData
问题:如何合并两个对象以创建一个最终对象。所以基本上,我希望它像这样:
[
"review": "Ggg",
"review_id": "review_38405",
"status": "active"
"_id": "5e0c43ea5bd0377f4cfdfa19",
"user_name": "123user",
"rating": 5,
"booking_id": "Booking_23749"
]
更新
有关我实际上要实现的目标的更多详细信息:
如果json中有四个记录,如下所示:
{
"user_name": "123user",
"review": "Ggg",
"booking_id": "Booking1",
"review_id": "review_38405",
"status": "active"
},
{
"_id": "5e0c43ea5bd0377f4cfdfa19",
"user_name": "123user",
"rating": 5,
"booking_id": "Booking1"
},
{
"user_name": "123user",
"review": "Ggg",
"booking_id": "Booking2",
"review_id": "review_38405",
"status": "active"
},
{
"_id": "5e0c43ea5bd0377f4cfdfa19",
"user_name": "123user",
"rating": 5,
"booking_id": "Booking2"
}
我需要像这样合并Booking1和Booking2:
{
"user_name": "123user",
"review": "Ggg",
"booking_id": "Booking1",
"review_id": "review_38405",
"status": "active"
"_id": "5e0c43ea5bd0377f4cfdfa19",
"rating": 5,
},
{
"user_name": "123user",
"review": "Ggg",
"booking_id": "Booking2",
"review_id": "review_38405",
"status": "active"
"_id": "5e0c43ea5bd0377f4cfdfa19",
"rating": 5,
}
我希望现在已经很清楚了。
最佳答案
JSON
给定这个JSON
let data = """
{
"status": "Success",
"records": [
{
"user_name": "123user",
"review": "Ggg",
"booking_id": "Booking_23749",
"review_id": "review_38405",
"status": "active"
},
{
"_id": "5e0c43ea5bd0377f4cfdfa19",
"user_name": "123user",
"rating": 5,
"booking_id": "Booking_23749"
}
]
}
""".data(using: .utf8)!
并给出相关的Codable结构
我们需要将
merged(with:
方法添加到Record
结构中struct Response: Decodable {
let status: String
let records: [Record]
struct Record: Decodable {
let userName: String?
let review: String?
let bookingID: String
let reviewID: String?
let status: String?
let id: String?
let rating: Int?
enum CodingKeys: String, CodingKey {
case userName = "user_name"
case review
case bookingID = "booking_id"
case reviewID = "review_id"
case status
case id = "_id"
case rating
}
func merged(with record: Record) -> Record? {
guard bookingID == record.bookingID else { return nil }
return Record(userName: userName ?? record.userName,
review: review ?? record.review,
bookingID: bookingID,
reviewID: reviewID ?? record.reviewID,
status: status ?? record.status,
id: id ?? record.id,
rating: rating ?? record.rating
)
}
}
}
解码和合并
现在我们可以解码并合并具有相同
Record(s)
的recordID
do {
let response = try JSONDecoder().decode(Response.self, from: data)
let mergedRecords = response
.records
.reduce(into: [String: Response.Record]()) { (result, record) in
guard let existingRecord = result[record.bookingID] else {
result[record.bookingID] = record
return
}
let merged = existingRecord.merged(with: record)
result[record.bookingID] = merged
}
.values
print(mergedRecords)
} catch {
print(error)
}
结果
[
Response.Record(
userName: Optional("123user"),
review: Optional("Ggg"),
bookingID: "Booking_23749",
reviewID: Optional("review_38405"),
status: Optional("active"),
id: Optional("5e0c43ea5bd0377f4cfdfa19"),
rating: Optional(5)
)
]
马卡丁素
此代码适用于输入JSON的
records
字段中的任意数量的元素。更新
我用您的新输入JSON测试了我的代码
let data = """
{
"status": "Success",
"records": [
{
"user_name": "123user",
"review": "Ggg",
"booking_id": "Booking1",
"review_id": "review_38405",
"status": "active"
},
{
"_id": "5e0c43ea5bd0377f4cfdfa19",
"user_name": "123user",
"rating": 5,
"booking_id": "Booking1"
},
{
"user_name": "123user",
"review": "Ggg",
"booking_id": "Booking2",
"review_id": "review_38405",
"status": "active"
},
{
"_id": "5e0c43ea5bd0377f4cfdfa19",
"user_name": "123user",
"rating": 5,
"booking_id": "Booking2"
}
]
}
""".data(using: .utf8)!
我得到了预期的结果
[
Response.Record(userName: Optional("123user"),
review: Optional("Ggg"),
bookingID: "Booking1",
reviewID: Optional("review_38405"),
status: Optional("active"),
id: Optional("5e0c43ea5bd0377f4cfdfa19"),
rating: Optional(5)),
Response.Record(userName: Optional("123user"),
review: Optional("Ggg"),
bookingID: "Booking2",
reviewID: Optional("review_38405"),
status: Optional("active"),
id: Optional("5e0c43ea5bd0377f4cfdfa19"),
rating: Optional(5))
]
因此,请仔细检查您是否完全按照我的指示进行;)
关于ios - 在Swift中合并两个结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59551313/