Swift中含空字符串的日期字符串数组排序方案
解决含空日期字符串的自定义对象数组排序问题
嘿,这个场景我碰到过好几次,核心思路其实很清晰:先把.medium格式的日期字符串转成真正的Date类型(毕竟字符串直接排序逻辑会乱,空字符串更是没法直接比),然后专门处理空日期的排序规则就行。
第一步:先搞定日期解析的工具
首先得搞一个靠谱的DateFormatter,专门用来解析你这种"Mar 13, 2018"格式的日期字符串:
let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.locale = Locale(identifier: "en_US_POSIX") // 必须指定英文区域,不然系统是中文的话会解析失败 return formatter }()
这里一定要加locale,不然如果用户的系统语言是中文,DateFormatter会试图用中文格式解析英文日期,直接返回nil。
第二步:写排序逻辑,处理所有边界情况
排序的时候要覆盖三种场景:两个都有有效日期、两个都是空、一个有一个空。我直接给你完整的可运行代码,基于你提供的testObj:
// 先补全你的自定义对象定义(假设是这样) struct testObj { let dateProp: String } // 你的测试数据 let objA = testObj(dateProp: "Mar 13, 2018") let objB = testObj(dateProp: "Apr 13, 2018") let objC = testObj(dateProp: "Apr 12, 2018") let objD = testObj(dateProp: "") let arr: [testObj] = [objA, objB, objC, objD] // 核心排序逻辑 let sortedArr = arr.sorted { obj1, obj2 in // 把两个对象的日期字符串转成Date let date1 = dateFormatter.date(from: obj1.dateProp) let date2 = dateFormatter.date(from: obj2.dateProp) switch (date1, date2) { case (.some(let d1), .some(let d2)): // 两个都有有效日期:按升序排(旧日期在前),要降序就改成d1 > d2 return d1 < d2 case (.none, .some): // 第一个是空日期,第二个有:把空的放在前面,不想的话就返回false return true case (.some, .none): // 第一个有日期,第二个是空:把空的放在后面,不想的话就返回true return false case (.none, .none): // 两个都空:保持原顺序(稳定排序),或者直接返回false也可以 return false } } // 验证结果 sortedArr.forEach { print($0.dateProp) } // 输出:""、"Mar 13, 2018"、"Apr 12, 2018"、"Apr 13, 2018"
灵活调整的小技巧
- 如果你想把空日期放在最后,只需要修改两个case的返回值:把
case (.none, .some):改成false,case (.some, .none):改成true。 - 日期格式化器尽量复用,别在排序闭包里每次都创建,不然数组大了会影响性能。
- 如果你的日期格式不是英文的,记得把
locale改成对应地区的标识符,比如中文用zh_CN。
内容的提问来源于stack exchange,提问作者user3628240
相关产品推荐
相关产品推荐

