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

Ios 按自定义时间间隔对对象数组进行分组,ios,swift,mapping,grouping,Ios,Swift,Mapping,Grouping,我有一系列的帖子,我现在每天都在分组。我使用以下功能来执行此操作 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)! } pr

我有一系列的帖子,我现在每天都在分组。我使用以下功能来执行此操作

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]
    }
    
    这不是一个优雅的解决方案,但它解决了问题,请随意优化此函数,特别是因为日期计算可能会缓慢

    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
                    }
                }
            }
        }
    }
    
    private func预裂过程(从日期:date)->date{
    让calendar=calendar.current
    让isToday=calendar.isDateInToday(日期)
    如果是今天{
    返回日期
    }否则{
    let wasDayed=日历。IsDateinDayed(日期)
    如果是昨天{
    返回日期
    }否则{
    让bowComponents=calendar.dateComponents([.weekOfYear],from:date)
    让BeginingOfWeek=calendar.date(from:bowComponents)!//请处理错误
    如果开始周<日期{
    返回日期
    }否则{
    让bomComponents=calendar.dateComponents([.month],from:date)
    让beginningsOfMonth=calendar.date(from:bomComponents)!//请处理错误
    如果月初<日期{
    返回日期
    }否则{
    var components=DateComponents()
    组件。年份=1970年
    组件。月份=01
    组件。天=01
    让oldDate=calendar.date(from:components)!
    返回旧日期
    }
    }
    }
    }
    }
    

    在调用
    splitDay
    函数之前添加此项,因为这不会将返回日期减少到相同的日期。

    由于您试图将数据分组为“今天”、“昨天”、“本周”和“本月”,您应该首先创建一个类型来表示这些组:

    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
    }
    
    然后,您的
    postssection
    结构将具有
    PostGroup
    属性,而不是
    Date
    属性:

    struct PostSection {
        let group: PostGroup
        let posts: [Post]
    }
    
    现在我们只需要一个可以传递到
    字典(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)
        }
    }