Swift:含布尔值与可选日期的人员数组多条件排序实现问询
实现复合排序的解决方案
这个复合排序需求可以通过分层次的逻辑判断轻松实现,我们在sort(by:)的闭包里先区分客户分组,再处理每组内的排序规则,下面是具体的实现代码和细节解释:
完整实现代码
customersList.sort { // 第一步:先确保未购买的客户排在已购买客户前面 if !$0.hasPurchased && $1.hasPurchased { return true } else if $0.hasPurchased && !$1.hasPurchased { return false } // 第二步:同一分组内执行对应排序规则 if !$0.hasPurchased { // 未购买组:按姓名升序,这里优化了可选值处理避免崩溃 return ($0.name ?? "").compare($1.name ?? "") == .orderedAscending } else { // 已购买组:按purchaseDate升序,同时处理日期可选值的安全问题 guard let date0 = $0.purchaseDate, let date1 = $1.purchaseDate else { // 若存在已购买但无日期的客户,默认把无日期的排在前面,可按需调整 return $0.purchaseDate == nil } return date0.compare(date1) == .orderedAscending } }
代码逻辑拆解
- 分组优先级判断:先对比两个客户的
hasPurchased状态,直接确保未购买(false)的客户始终排在已购买(true)客户的前面。 - 未购买组排序:沿用你之前的姓名升序逻辑,但做了安全优化——用
?? ""处理name为nil的情况,避免强制解包引发崩溃。 - 已购买组排序:针对
purchaseDate的可选性做了安全校验,如果两个客户都有购买日期,就按日期升序排列;如果其中一个无日期,默认把无日期的排在前面,你可以根据实际业务需求修改这部分逻辑(比如把无日期的排在后面)。
更简洁的写法(利用Swift元组比较特性)
Swift支持元组的直接顺序比较,我们可以用这个特性大幅简化代码:
customersList.sort { // 把分组、姓名、日期打包成元组,Swift会依次比较每个元素 let sortKey0 = ($0.hasPurchased ? 1 : 0, $0.name ?? "", $0.purchaseDate ?? Date.distantPast) let sortKey1 = ($1.hasPurchased ? 1 : 0, $1.name ?? "", $1.purchaseDate ?? Date.distantPast) return sortKey0 < sortKey1 }
这个写法里,我们用0标记未购买组、1标记已购买组,元组比较会先判断分组优先级(0 < 1,所以未购买组在前);分组相同则比较姓名;姓名相同则比较日期(用Date.distantPast处理无日期的情况,让无日期的排在该组最前面)。
内容的提问来源于stack exchange,提问作者Creanomy
相关产品推荐
相关产品推荐

