If you want to avoid making new objects every time you go through the sort block then you could make a Dictionary, with the original Date as the Key and the Day/Month components as the value. This can can then be sorted and returned as an Array of the original dates.
func sortDatesByDayMonth(_ dates: [Date]) -> [Date] {
let calendar = Calendar.current
var datesWithDayMonthOnly = [Date : Date]()
for date in dates {
var dateComponents = DateComponents()
dateComponents = calendar.dateComponents([.day, .month], from: date)
let dayMonthDate = calendar.date(from: dateComponents)
datesWithDayMonthOnly[date] = dayMonthDate
}
return datesWithDayMonthOnly.sorted { $0.1 < $1.1 }.map { $0.key }
}
Or as an Array of Tuples, which would handle the rare case that two dates are precisely the same:
func sortDatesByDayMonth(_ dates: [Date]) -> [Date] {
let calendar = Calendar.current
var datesWithDayMonthOnly = [(date: Date, dayMonthDate: Date)]()
for date in dates {
var dateComponents = DateComponents()
dateComponents = calendar.dateComponents([.day, .month], from: date)
if let dayMonthDate = calendar.date(from: dateComponents) {
datesWithDayMonthOnly.append((date: date, dayMonthDate: dayMonthDate))
}
}
return datesWithDayMonthOnly.sorted { $0.dayMonthDate < $1.dayMonthDate }.map { $0.date }
}
Example:
var dates = [Date]()
for _ in 1...20 {
dates.append(Date(timeIntervalSince1970: Double.random(in: 0...Date().timeIntervalSince1970)))
}
sortDatesByDayMonth(dates)
Example Output:
[2005-01-08 18:26:45 +0000,
1994-01-13 15:13:10 +0000,
1986-01-26 03:48:43 +0000,
1992-02-15 10:40:06 +0000,
2005-03-20 12:33:41 +0000,
1998-04-04 13:23:33 +0000,
1982-04-25 17:21:55 +0000,
1976-05-16 20:59:00 +0000,
1995-05-20 03:53:41 +0000,
2006-07-23 06:50:19 +0000,
2017-08-23 08:16:49 +0000,
1989-08-30 17:47:49 +0000,
1986-09-07 03:05:49 +0000,
1990-09-08 16:09:47 +0000,
2007-10-14 03:46:24 +0000,
1974-10-16 16:06:53 +0000,
1977-11-04 14:15:43 +0000,
1974-11-09 08:55:11 +0000,
2011-12-02 07:23:57 +0000,
1983-12-31 00:22:57 +0000]