如何在 Swift 中聚合 [关闭]
Posted
技术标签:
【中文标题】如何在 Swift 中聚合 [关闭]【英文标题】:How to Aggregate in Swift [closed] 【发布时间】:2016-05-18 17:44:36 【问题描述】:我在 swift 中使用聚合函数时遇到问题,我将一个数字保存到 coredata 中。但是我一直在尝试获取它并按某个实体组织它。例如,加利福尼亚有 150 只狗,加利福尼亚有 60 只猫,俄勒冈州有 200 只狗,俄勒冈州有 60 只猫。我把它放到一个 VC 中,让人们输入每个州有多少只狗或猫。但在下一个中,我希望能够按州排序并合计每个州的动物数量。
【问题讨论】:
【参考方案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:,而不是用于简单的聚合。 谢谢,抱歉还有一个问题,您如何获得关系的双箭头? 那是To-Many relationship 抱歉,我在过去几周一直在尝试这个问题,但我似乎无法正确保存。你是怎么把它保存在这里的,我正在使用实体描述来保存它。这是正确的还是有更好的方法。以上是关于如何在 Swift 中聚合 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章