按自定义时间间隔对对象数组进行分组
Posted
技术标签:
【中文标题】按自定义时间间隔对对象数组进行分组【英文标题】:Grouping Array of Objects by Custom Time Intervals 【发布时间】:2021-04-29 20:57:36 【问题描述】:我有一系列帖子,目前按天分组。我使用以下函数来做到这一点;
private func splitDay(from date: Date) -> Date
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day], from: date)
return calendar.date(from: components)!
private func sectionPosts(posts: [Post])
let groups = Dictionary(grouping: posts) (posts) in
return splitDay(from: Date(timeIntervalSince1970: posts.createdOn))
self.sections = groups.map (date, posts) in
return PostSection(date: date, posts: posts)
但是,我想实现一个自定义分组,如下所示;
-
今天
昨天
本周
本月
老年人
如何将其构建到我的分组功能中?我的部分结构是这样的;
struct PostSection
var date: Date
var posts: [Post]
【问题讨论】:
【参考方案1】:这不是一个优雅的解决方案,但它解决了问题,请随时优化此功能,特别是因为日期计算可能慢。
private func preSplitProcess(from date: Date) -> Date
let calendar = Calendar.current
let isToday = calendar.isDateInToday(date)
if isToday
return date
else
let wasYesterday = calendar.isDateInYesterday(date)
if wasYesterday
return date
else
let bowComponents = calendar.dateComponents([.weekOfYear], from: date)
let beginningOfWeek = calendar.date(from: bowComponents)! // Handle errors, please
if beginningOfWeek < date
return date
else
let bomComponents = calendar.dateComponents([.month], from: date)
let beginningsOfMonth = calendar.date(from: bomComponents)! // Handle errors, please
if beginningsOfMonth < date
return date
else
var components = DateComponents()
components.year = 1970
components.month = 01
components.day = 01
let oldDate = calendar.date(from: components)!
return oldDate
在调用 splitDay
函数之前添加它,因为这不会将返回日期减少到同一日期。
【讨论】:
【参考方案2】:由于您尝试将数据分组为“今天”、“昨天”、“本周”和“本月”等组,您应该首先创建一个类型来表示这些组:
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
那么您的PostSection
结构将具有PostGroup
属性,而不是Date
属性:
struct PostSection
let group: PostGroup
let posts: [Post]
现在我们只需要一个可以传递给Dictionary(grouping:by:)
的函数(Post) -> PostGroup
。这可以通过将发布日期的日期组件与今天的日期组件进行比较来实现:
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
完成它:
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)
【讨论】:
以上是关于按自定义时间间隔对对象数组进行分组的主要内容,如果未能解决你的问题,请参考以下文章
如何按自定义顺序对 JavaScript 中的数组进行排序? [复制]