Since you are trying to group your data into groups such as "today", "yesterday", "this week" and "this month", you should first create a type to represent these groups:
enum PostGroup {
case today
case yesterday
case thisWeek
case thisMonth
case older
case coming // added "coming" group so that the groups cover all possible dates
}
Then your PostSection
struct would have a PostGroup
property, rather than a Date
property:
struct PostSection {
let group: PostGroup
let posts: [Post]
}
Now we just need a function that goes (Post) -> PostGroup
that we can pass to Dictionary(grouping:by:)
. This can be implemented just by comparing the date components of the post date with that of today:
func group(for post: Post) -> PostGroup {
let today = Date()
let calendar = Calendar.current
let postDateComponents = calendar.dateComponents([.year, .month, .day], from: post.createdOn)
let todayDateComponents = calendar.dateComponents([.year, .month, .day], from: today)
if postDateComponents == todayDateComponents {
return .today
}
let daysDifference = calendar.dateComponents([.day], from: postDateComponents, to: todayDateComponents)
if daysDifference.day == 1 {
return .yesterday
}
let postWeekComponents = calendar.dateComponents([.weekOfYear, .yearForWeekOfYear], from: post.createdOn)
let todayWeekComponents = calendar.dateComponents([.weekOfYear, .yearForWeekOfYear], from: today)
if postWeekComponents == todayWeekComponents {
return .thisWeek
}
if postDateComponents.year == todayDateComponents.year &&
postDateComponents.month == todayDateComponents.month {
return .thisMonth
}
if post.createdOn < today {
return .older
} else {
return .coming
}
}
To finish it off:
private func sectionPosts(posts: [Post]) {
let groups = Dictionary(grouping: posts, by: group(for:))
self.sections = groups.map { (group, posts) in
return PostSection(group: group, posts: posts)
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…