Last active
July 18, 2022 09:05
-
-
Save ElegyD/abc5dc819c9e7286452a6eb7e92fa9bb to your computer and use it in GitHub Desktop.
Group a Swift Model by day with ascending or descending order (Swift 5) E.g.: for a UITableView with sections
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
extension Sequence { | |
func groupByDay(dateKey: (Iterator.Element) -> Date, order: ComparisonResult = .orderedAscending) -> [[Iterator.Element]] { | |
var groups: [[Iterator.Element]] = [] | |
for element in self { | |
let key = dateKey(element) | |
guard let dayIndex = groups.firstIndex(where: { $0.contains(where: { Calendar.current.isDate(dateKey($0), inSameDayAs: key) }) }) else { | |
guard let nextIndex = groups.firstIndex(where: { $0.contains(where: { dateKey($0).compare(key) == order }) }) else { | |
groups.append([element]) | |
continue | |
} | |
groups.insert([element], at: nextIndex) | |
continue | |
} | |
guard let nextIndex = groups[dayIndex].firstIndex(where: { dateKey($0).compare(key) == order }) else { | |
groups[dayIndex].append(element) | |
continue | |
} | |
groups[dayIndex].insert(element, at: nextIndex) | |
} | |
return groups | |
} | |
} | |
// Usage: | |
struct Model { | |
let date: Date | |
let text: String | |
} | |
let modelArray = [ | |
Model(date: Date(), text: "Original Date"), | |
Model(date: Date().addingTimeInterval(86400), text: "+1 day"), | |
Model(date: Date().addingTimeInterval(172800), text: "+2 days"), | |
Model(date: Date().addingTimeInterval(86401), text: "+1 day & +1 second"), | |
Model(date: Date().addingTimeInterval(172801), text: "+2 days & +1 second"), | |
Model(date: Date().addingTimeInterval(86400), text: "+1 day"), | |
Model(date: Date().addingTimeInterval(172800), text: "+2 days") | |
] | |
let groupSorted = modelArray.groupByDay(dateKey: { $0.date }) | |
print(groupSorted) // [["+2 days & +1 second", "+2 days", "+2 days"], ["+1 day & +1 second", "+1 day", "+1 day"], ["Original Date"]] | |
let groupSortedDesc = modelArray.groupByDay(dateKey: { $0.date }, order: .orderedDescending) | |
print(groupSortedDesc) // [["Original Date"], ["+1 day", "+1 day", "+1 day & +1 second"], ["+2 days", "+2 days", "+2 days & +1 second"]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment