swift - 核心数据: Get most frequent value used for an attribute

标签 swift core-data

如何获取核心数据中某个属性最常用的值?

假设我们的实体表是:

--------------------------
|   Name   |   Company   |
--------------------------
|   John   |  Boring Co. |
|   Jane   |  Boring Co. |
|  Robert  |  Boring Co. |
|   Mary   | MoneyPal Co |
|   Jenn   | MoneyPal Co |
--------------------------

我的目标是获取最重复的值作为“公司”属性,即本例中的 Boring Co.,而不获取每个实体并在可能的情况下循环遍历每个项目。

最佳答案

我想分享我最终使用的内容,以防有人登陆此页面寻找类似问题的答案。我的初衷是使用核心数据/SQL 获取技术或某种特殊谓词来实现此目的,但我认为没有。所以我实现了以下内容:

class CoreData_User:NSManagedObject{
    static func getMostFrequentCompany(context: NSManagedObjectContext ) -> String?{
        // We get a list of distinc Company entries
        guard let companies:[String] = CoreData_User.getDistinctCompanies(context: context) else { return nil }

        var maxRepeatedCompany:String = ""
        var maxRepeatCount:Int = 0

        // Then we loop through them to find which one is most oftenly used
        for currentCompany in companies{
            let currentCompanyRepeatCount:Int = CoreData_User.count(withCompany: currentCompany, context: context)
            if currentCompanyRepeatCount > maxRepeatCount{
                maxRepeatedCompany = currentCompany
                maxRepeatCount = currentCompanyRepeatCount
            }
        }
        if maxRepeatCount < 1 || maxRepeatedCompany.isEmpty {
            return nil
        } else {
            return maxRepeatedCompany
        }
    }

    static func getDistinctCompanies(context: NSManagedObjectContext ) -> [String]?{
        let request:NSFetchRequest<NSFetchRequestResult> = CoreData_User.fetchRequest()

        let companyAttributeName:String = "Company"

        request.resultType = .dictionaryResultType
        request.propertiesToFetch = [companyAttributeName]
        request.returnsDistinctResults = true
        var results:[String] = [String]()

        context.performAndWait{
            do{
                guard let fetchResults = try context.fetch(request) as? [NSDictionary] else { return }

                for item in fetchResults{
                    if let company = (item as AnyObject).value(forKey: companyAttributeName) as? String{
                        results.append(company)
                    }
                }
            } catch {
                print("Failed to get company names")
            }
        }

        if results.count > 0 {
            return results
        } else {
            return nil
        }
    }
    static func count(withCompany company: String, context: NSManagedObjectContext) -> Int{
        let request = NSFetchRequest<T>(entityName: type.entity().name!)
        request.includesSubentities = false
        request.predicate = NSPredicate(format: "Company ==[c] %@", company)

        var fetchResult:Int?
        context.performAndWait{
            fetchResult = try? context.count(for: request)
        }

        if let count = fetchResult {
            return count
        } else {
            return 0
        }
    }
}

欢迎任何有关改进和优化方法的建议。

关于swift - 核心数据: Get most frequent value used for an attribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52992371/

相关文章:

uinavigationbar - 在 iOS8 Swift 中更改 UINavigationBar 标题

ios - Crashlytics:仪表板中显示了一些崩溃,但没有发现问题

ios - 解析注册验证

ios - SwiftyJSON 不重新加载 UITableView

ios - Objective C : How to create self. 以编程方式在安全区域内查看

objective-c - 托管对象上下文未保存到持久存储

ios - 如何回滚临时上下文的更改?

ios - NSPredicate 和 Core Data 多表查询

objective-c - 处理 addPersistentStoreWithType 中的错误

iPhone - NSPredicate(添加更多过滤器)