【问题标题】:How to Aggregate in Swift [closed]如何在 Swift 中聚合 [关闭]
【发布时间】:2016-05-18 17:44:36
【问题描述】:

我在 swift 中使用聚合函数时遇到问题,我将一个数字保存到 coredata 中。但是我一直在尝试获取它并按某个实体组织它。例如,加利福尼亚有 150 只狗,加利福尼亚有 60 只猫,俄勒冈州有 200 只狗,俄勒冈州有 60 只猫。我把它放到一个 VC 中,让人们输入每个州有多少只狗或猫。但在下一个中,我希望能够按州排序并合计每个州的动物数量。

【问题讨论】:

    标签: ios swift core-data swift2 aggregate


    【解决方案1】:

    您可以使用 NSExpression 类从 CoreData 获取聚合信息。这是我专门为您的案例创建的示例,因为我以前从未这样做过并且发现这很有趣;)

    我的 CoreData 模型如下所示:

    对于 Animal 的类型我使用枚举:

    enum AnimalType: Int {
        case Cat, Dog
    }
    

    视图控制器的代码:

    class AggregationResult {
        let locationName: String
        let animalType: AnimalType
        let count: Int
    
        init(locationName: String, animalType: AnimalType, count: Int) {
            self.locationName = locationName
            self.animalType = animalType
            self.count = count
        }
    }
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var tableView: UITableView!
    
        private var dataSource: [AggregationResult] = []
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            load()
        }
    
        private func load() {
    
            let countExpressionDesc = NSExpressionDescription()
            countExpressionDesc.name = "countAnimals"
            countExpressionDesc.expression = NSExpression(forFunction: "count:", arguments: [NSExpression(forKeyPath: "type")])
            countExpressionDesc.expressionResultType = .Integer32AttributeType
    
            let request = NSFetchRequest(entityName: "Animal")
            request.propertiesToFetch = ["location.name", "type", countExpressionDesc]
            request.propertiesToGroupBy = ["location.name", "type"] // <-- all these properties should be put in 'propertiesToFetch' otherwise we will have crash
            //request.predicate = NSPredicate(format: "location.name == %@", argumentArray: ["Oregon"]) // <-- uncomment to find animals from Oregon only
            request.resultType = .DictionaryResultType
    
            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
            let results = try! appDelegate.managedObjectContext.executeFetchRequest(request)
    
            if let results = results as? [NSDictionary] {
    
                print("results: \(results)")
    
                for dict in results {
                    if let
                        name = dict["location.name"] as? String,
                        type = dict["type"] as? Int,
                        atype = AnimalType(rawValue: type),
                        count = dict["countAnimals"] as? Int {
    
                        let ar = AggregationResult(locationName: name, animalType: atype, count: count)
                        dataSource.append(ar)
                    }
                }
    
                tableView.reloadData()
            }
        }
    }
    
    extension ViewController: UITableViewDataSource {
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return dataSource.count
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
    
            let item = dataSource[indexPath.row]
            cell.textLabel!.text = "\(item.locationName)"
            cell.detailTextLabel!.text = "\(item.count) \(item.animalType == .Cat ? "cats" : "dogs")"
    
            return cell
        }
    }
    

    你感兴趣的获取放在load函数中。 最后我得到的结果是:

    results: [{
        countAnimals = 60;
        "location.name" = California;
        type = 0;
    }, {
        countAnimals = 150;
        "location.name" = California;
        type = 1;
    }, {
        countAnimals = 100;
        "location.name" = Oregon;
        type = 0;
    }, {
        countAnimals = 200;
        "location.name" = Oregon;
        type = 1;
    }]
    

    表格看起来像:

    希望这会有所帮助:)

    【讨论】:

    • 只是好奇,这样可以算出狗的数量吗?顺便说一句,非常感谢。
    • 如果你想要狗的总数,只需从请求的两个属性列表(propertiesToFetch、propertiesToGroupBy)中删除“location.name”。另一种选择是使用 NSManagedObjectContext 的方法countForFetchRequest:,而不是用于简单的聚合。
    • 谢谢,抱歉还有一个问题,您如何获得关系的双箭头?
    • 抱歉,我在过去几周一直在尝试这个问题,但我似乎无法正确保存。你是怎么把它保存在这里的,我正在使用实体描述来保存它。这是正确的还是有更好的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2014-03-05
    • 2010-10-30
    • 2021-07-26
    • 2014-08-31
    • 2019-12-19
    相关资源
    最近更新 更多