按月/年分组 FechedResults 以显示带有部分的 swiftui 列表

Posted

技术标签:

【中文标题】按月/年分组 FechedResults 以显示带有部分的 swiftui 列表【英文标题】:Grouping FechedResults by Month/Year to display a swiftui list with sections 【发布时间】:2021-02-06 13:33:23 【问题描述】:

我有一个包含日期属性的核心数据实体 (LogEntry)。我正在尝试将视图迁移到 SwiftUI,并且该视图必须显示按年月分组(并按时间顺序排序)的所有日志条目,如下所示:

2017 年 6 月

日志条目 1(6 月 10 日) 日志条目 2(6 月 16 日) 日志条目 3(6 月 17 日)

2017 年 7 月

日志条目 1(7 月 1 日) 日志条目 2(7 月 3 日) 等

我已经能够使用此代码实现所需的分组:

func group(_ result : FetchedResults<LogEntry>) -> [[LogEntry]] 
    return  Dictionary(grouping: result) (element : LogEntry)  in
        sectionDateFormatter.string(from: element.date as Date)
    .values.map$0


var body: some View 
    NavigationView 
        List 
            ForEach(group(logEntries), id: \.self)  (section: [LogEntry]) in  //Works but not ordered
                Section(header: Text( self.sectionDateFormatter.string(from: section[0].date as Date))) 
                    ForEach(section, id: \.self)  logEntry in
                        HStack 
                            Text("\(self.logDateFormatter.string(from: logEntry.date as Date))")
                            Spacer()
                            Text("\(logEntry.total) m").font(.subheadline)
                        
                    
                
            .id(logEntries.count)
        
        .listStyle(PlainListStyle())
    

我一直在尝试添加排序,但我似乎无法在 SwiftUI 的上下文中找到正确的方法。

我试过这个:

func update(_ result : FetchedResults<LogEntry>)-> [[LogEntry]]
        return  Dictionary(grouping: result) (element : LogEntry)  in
            sectionDateFormatter.string(from: element.date as Date)
        .values.sorted()  $0[0].date! < $1[0].date! 
    

...但我收到“表达式类型不明确,没有更多上下文”错误,并且无法编译。

我也试过这个:

func groupedByYearMonth(_ result: FetchedResults<LogEntry>) -> [Date: [LogEntry]] 
      let empty: [Date: [LogEntry]] = [:]
      return logEntries.reduce(into: empty)  acc, cur in
        let components = Calendar.current.dateComponents([.year, .month], from: cur.date as Date)
          let date = Calendar.current.date(from: components)!
          let existing = acc[date] ?? []
          acc[date] = existing + [cur]
      
    

...但在这种情况下,我不知道如何调整 SwiftUI 列表 ForEach 以使用它。

任何指针将不胜感激!

【问题讨论】:

this 回答你的问题了吗? @pbasdf - 我之前尝试过类似的方法 - 当我调整建议的解决方案时,我最终在 .values.sorted() 行上出现“表达式类型不明确而没有更多上下文”和代码不再编译... 【参考方案1】:

如果您使用临时字典中可以正确排序的不同键,则可以对获取的结果进行排序。因此,对于函数中使用的 DateFormatter,我将格式设置为“yyyy-MM”。

请注意,我首先对函数的输入进行排序,但如果获取的结果已经按我推荐的date 排序,则不需要此步骤。

func group(_ result : FetchedResults<LogEntry>) -> [[LogEntry]] 
    let sorted = result.sorted  $0.date < $1.date  

    return Dictionary(grouping: sorted)  (element : LogEntry)  in
        dictionaryDateFormatter.string(from: element.date as Date)
    .sorted  $0.key < $1.key .map(\.value)

【讨论】:

以上是关于按月/年分组 FechedResults 以显示带有部分的 swiftui 列表的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent,按月/年分组

整个数据集的不同计数,按月分组

LINQ:在日期时间字段中按月和年分组

c# List<T> 按年分组,然后按月分组

按月、年分组的数据集运行总计

MagicalRecord - 获取按月/年分组的对象