给定Calls表:
+--------+--------+----------+ | caller | callee | duration | +--------+--------+----------+ | A | B | 3 | | B | C | 1 | | C | A | 2 | | B | A | 5 | +--------+--------+----------+
所需输出:
+------------+-------+ | subscriber | total | +------------+-------+ | A | 10 | | B | 9 | | C | 3 | +------------+-------+
如何设置NSFetchRequest以获得所需的输出?
发布于 2018-04-05 13:31:46
我不得不以某种方式解决它(下面的代码不是我应用程序中的实际代码,而是一个草图)。这是一种“混合”的解决方案,介于只读取(我怀疑这是可能的,因为CoreData缺乏联合)和完全内存中的解决方案之间。
class Subscriber:NSObject {
@objc dynamic var subscriber = 0
@objc dynamic var total = 0
init(dictionary: NSDictionary) {
if let s = dictionary["caller"] as? Int { subscriber = s}
if let t = dictionary["total"] as? Int { total = t }
super.init()
}
init(dictionary: NSDictionary, _:Bool) {
if let s = dictionary["callee"] as? Int { subscriber = s}
if let t = dictionary["total"] as? Int { total = t }
super.init()
}要获取do...catch中的Subscriber对象数组,请执行以下操作:
let req_a = NSFetchRequest<NSDictionary>(entityName:"Call")
let durExp = NSExpression(forKeyPath: "duration")
let sumDesc = NSExpressionDescription()
sumDesc.expression = NSExpression(forFunction: "sum:", arguments: [durExp])
sumDesc.name = "total"
sumDesc.expressionResultType = .integer64AttributeType
req_a.propertiesToGroupBy = ["caller"]
req_a.propertiesToFetch = ["caller", sumDesc]
req_a.resultType = .dictionaryResultType
let req_b = NSFetchRequest<NSDictionary>(entityName:"Call")
req_b.propertiesToGroupBy = ["callee"]
req_b.propertiesToFetch = ["callee", sumDesc]
req_b.resultType = .dictionaryResultType
var subscriberResults_a = try theMOC.fetch(req_a).map { return Subscriber(dictionary: $0) }
var subscriberResults_b = try theMOC.fetch(req_b).map { return Subscriber(dictionary: $0, true) }
/// Add values from duplicates
subscriberResults_a = subscriberResults_a?.map { a -> Subscriber in
guard let b = subscriberResults_b?.first(where: { $0.subscriber == a.subscriber }) else { return a }
a.total += b.total
return a
}
/// Filter out duplicates
subscriberResults_b = subscriberResults_b?.filter({ b -> Bool in
if let found = subscriberResults_a?.contains (where: { $0.subscriber == b.subscriber }) { return !found }
return true
})
subscriberArray = subscriberResults_a! + subscriberResults_b!还在寻找更好的解决方案。
https://stackoverflow.com/questions/49319076
复制相似问题