首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSFetchRequest两列和和

NSFetchRequest两列和和
EN

Stack Overflow用户
提问于 2018-03-16 18:56:31
回答 1查看 144关注 0票数 0

给定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以获得所需的输出?

EN

回答 1

Stack Overflow用户

发布于 2018-04-05 13:31:46

我不得不以某种方式解决它(下面的代码不是我应用程序中的实际代码,而是一个草图)。这是一种“混合”的解决方案,介于只读取(我怀疑这是可能的,因为CoreData缺乏联合)和完全内存中的解决方案之间。

代码语言:javascript
复制
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对象数组,请执行以下操作:

代码语言:javascript
复制
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!

还在寻找更好的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49319076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档