Swift中按日期分组排序订单字典失败问题求助
解决订单数据按日期分组后排序混乱的问题
问题根源
问题出在分组用的日期字符串格式与排序时的解析格式不匹配,导致排序逻辑中的日期解析失败,无法正确比较日期大小:
getDatebyString方法返回的是date.formatted(.dateTime.year().month().day()),这个格式化后的字符串并非标准的yyyy-MM-dd格式(可能是2024-5-16或本地化格式);- 排序时使用的
DateFormatter设置了dateFormat = "yyyy-MM-dd",无法正确解析getDatebyString返回的格式,导致guard let d1 = df.date(from:$0.key)触发失败分支,直接返回false,排序逻辑完全失效,最终结果呈现随机状态。
解决方案
方法一:统一日期字符串格式
修改getDatebyString返回标准的yyyy-MM-dd格式字符串,该格式的字符串可直接通过字典序比较得到正确的时间顺序,无需额外转换为Date类型:
func getDatebyString(date :String) -> String { let inputFormatter = DateFormatter() inputFormatter.locale = Locale(identifier: "en_US_POSIX") inputFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" guard let date = inputFormatter.date(from: date) else { return "" // 处理无效日期,避免强制解包崩溃 } let outputFormatter = DateFormatter() outputFormatter.dateFormat = "yyyy-MM-dd" return outputFormatter.string(from: date) } // 简化排序逻辑,直接比较字符串 func personsByMonth(persons : [Orderproperties]) { let dictionaryByMonth = Dictionary(grouping: persons, by: { getDatebyString(date: $0.dateCreated ?? "") }) .sorted{ $0.key < $1.key } print(dictionaryByMonth) for (key, orders) in dictionaryByMonth{ var item = [OrderItems]() for order in orders { let image = order.status == "completed" ? "delivered" : "inprogress" item.append(OrderItems( image: image, location: order.billing?.city ?? "", quantity: String(order.lineItems.count), state: order.status ?? "", price: order.total ?? "0" )) } ordersValue.append(OrderWithHeaders(headers: key , orderItems: item)) } }
方法二:直接用Date类型分组(更可靠)
跳过字符串转换的环节,直接将日期转为Date类型作为分组key,利用Date的原生比较逻辑确保排序正确,同时处理无效日期的边界情况:
func personsByMonth(persons : [Orderproperties]) { let inputFormatter = DateFormatter() inputFormatter.locale = Locale(identifier: "en_US_POSIX") inputFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" // 按日期(忽略时分秒)分组 let dictionaryByDate = Dictionary(grouping: persons) { order -> Date in guard let dateStr = order.dateCreated, let date = inputFormatter.date(from: dateStr) else { // 无效日期设为极早时间,确保排在最后 return Date.distantPast } // 提取日期部分,统一时分秒为0 return Calendar.current.startOfDay(for: date) } // 直接对Date类型key排序 let sortedGroups = dictionaryByDate.sorted { $0.key < $1.key } print(sortedGroups) for (dateKey, orders) in sortedGroups { // 将Date转为展示用的字符串格式 let displayFormatter = DateFormatter() displayFormatter.dateStyle = .short // 可根据需求修改格式 let displayDate = displayFormatter.string(from: dateKey) var item = [OrderItems]() for order in orders { let image = order.status == "completed" ? "delivered" : "inprogress" item.append(OrderItems( image: image, location: order.billing?.city ?? "", quantity: String(order.lineItems.count), state: order.status ?? "", price: order.total ?? "0" )) } ordersValue.append(OrderWithHeaders(headers: displayDate, orderItems: item)) } }
内容的提问来源于stack exchange,提问作者ichrak ben nejma
相关产品推荐
相关产品推荐

