按自定义时间间隔对对象数组进行分组

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) -&gt; 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 中的数组进行排序? [复制]

PHP按自定义顺序对工作日和月份-年份数组进行排序

对对象数组进行分组的最有效方法

在 Eloquent 中按自定义顺序对集合进行排序 [重复]

使用对象对数组项进行分组