有一組來自資料庫的用戶。
struct Model {
var name: String
var date: String
}
let data: [Model] = [
Model(name: "Mick", date: "12.09.2022"),
Model(name: "Donald", date: "12.09.2022"),
Model(name: "Melissa", date: "07.09.2022"),
Model(name: "Kerem", date: "12.09.2022"),
Model(name: "Caren", date: "24.09.2022"),
Model(name: "Jhon", date: "07.09.2022"),
Model(name: "Miles", date: "19.09.2022"),
Model(name: "Rick", date: "19.09.2022"),
]
我想要的是通過將具有相同日期的陣列分組來創建一個新陣列。
我想要的陣列:
let groupedData: [[Model]] = [
[
Model(name: "Caren", date: "24.09.2022")
],
[
Model(name: "Rick", date: "19.09.2022"),
Model(name: "Miles", date: "19.09.2022")
],
[
Model(name: "Mick", date: "12.09.2022"),
Model(name: "Donald", date: "12.09.2022"),
Model(name: "Kerem", date: "12.09.2022")
],
[
Model(name: "Jhon", date: "07.09.2022"),
Model(name: "Melissa", date: "07.09.2022")
]
]
我嘗試使用 for 回圈進入主陣列,但我無法得出任何結論,因為未來資料的大小是可變的。
uj5u.com熱心網友回復:
一種解決方案是創建一個以日期為鍵的臨時字典。每個日期字串的值是一個匹配模型的陣列。盡管最終分組的資料未按日期排序,但以下內容會產生所需的結果。由于 dd-MM-yyyy 格式的日期字串不能作為字串排序,因此我將日期排序留給讀者作為練習。
var temp = [String : [Model]]()
data.forEach {
var dateArray = temp[$0.date] ?? []
dateArray.append($0)
temp[$0.date] = dateArray
}
let groupedData: [[Model]] = temp.map { $0.value }
這個解決方案的好處是它只掃描記錄串列一次,并將每個記錄添加到以記錄日期為鍵的陣列中。
整個臨時字典實際上可以使用Dictionary(grouping:,by:)初始化程式創建。上面的代碼可以簡化為:
let groupedData: [[Model]] = Dictionary(grouping: data, by: { $0.date }).map { $0.value }
這在更簡單的代碼中給出了相同的結果。該Dictionary(grouping: data, by: { $0.date })部分替換了temp宣告和data.forEach回圈。最后的使用map { $0.value }與上面給出的最終陣列陣列相同,其中每個內部陣列具有相同的日期。
可以在一行中完成但效率大大降低的另一種解決方案如下:
let groupedData: [[Model]] = Set<String>(data.map { $0.date }).map { date in data.filter { $0.date == date } }
此解決方案的問題在于,data陣列將針對每個唯一日期進行過濾。如果您有數千條記錄,其中包含數百或數千個不同的日期,那么性能將會很糟糕。
解釋該行:
該Set<String>(data.map { $0.date })部件從所有日期創建一個集合。這會從所有記錄中構建一個唯一的日期串列。
其余.map { date in data.filter { $0.date == date } }的通過過濾具有匹配日期的記錄串列來創建一個陣列。這是針對每個唯一日期完成的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/526005.html
標籤:IOS迅速
