【问题标题】: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)
    }
}

但是,我想实现一个自定义分组,如下所示;

  1. 今天
  2. 昨天
  3. 本周
  4. 本月
  5. 老年人

如何将其构建到我的分组功能中?我的部分结构是这样的;

struct PostSection {
    var date: Date
    var posts: [Post]
}

【问题讨论】:

    标签: ios swift mapping grouping


    【解决方案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)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-01-30
        • 2021-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-04
        相关资源
        最近更新 更多