首页 > 解决方案 > SwiftUI:按核心数据属性分组和求和

问题描述

问题是:如何按属性对 Core Data 对象进行分组,然后对它们执行简单的计算(比如说求和)?

我已经为此找到了一些类似的答案(比如这个),但似乎没有一个是决定性的,而且所有人都在为 Swift 做好准备(而我正在研究 SwiftUI)。

例如,我有一个如下所示的核心数据模型:

extension Items {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Items> {
        return NSFetchRequest<Items>(entityName: "Items")
    }

    @NSManaged public var id: UUID?
    @NSManaged public var cost: Int16
    @NSManaged public var type: String
}

Home()视图中,我想按类型分组,然后找到每种类型中所有对象的总支付金额(即成本总和)。

到目前为止,我已经尝试过制作一个特殊的group()功能(有点像这个问题),但收到错误消息"Cannot find 'i' in scope"

struct Home: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(entity: Items.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Items.type, ascending: true)]) var items: FetchedResults<Items>

var body: some View {
        ForEach(group(items), id: \.self) { [i] in
            Text("\([i].cost.reduce(0,+))")
           }
      }
}

func group(_ result : FetchedResults<Items>)-> [[Items]] {
        
    return Dictionary(grouping: result) { $0.type }
            .sorted(by: {$0.key < $1.key})
            .map {$0.value}
        
    }

这肯定不会这么难吧?非常欢迎任何帮助!

标签: core-dataswiftui

解决方案


您不应该在 [i] in 中的 i 周围加上括号。这样的括号捕获一个值,但您没有要捕获的变量——您只是获得了闭包的参数。

ForEach(group(items), id: \.self) { i in

在您的下一行,您正在处理一个多维数组。您不能直接访问属性,但您可以map首先:

Text("\(i.map(\.cost).reduce(0,+))")

您也可以稍微不同地构造它并通过执行以下操作删除地图:

i.reduce(0,{ $0 + $1.cost })

推荐阅读