我有一个视图,我希望获得“百分比”属性的平均值,而无需将所有对象(及其他属性)从Core Data加载到内存中。我已经在Apple的文档中找到了如何做到这一点,但问题是我想将平均百分比的对象限制为另一个名为“numberAsked”的属性大于0的对象。我认为这是我可以做的事情与NSPredicate。
这就是我所拥有的:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Statistics" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"numberAsked > 0"];
[request setPredicate:searchPredicate];
[request setResultType:NSDictionaryResultType];
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"percentCorrect"];
NSExpression *averagePercentExpression = [NSExpression expressionForFunction:@"average:"
arguments:[NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName:@"averagePercentageCorrect"];
[expressionDescription setExpression:averagePercentExpression];
[expressionDescription setExpressionResultType:NSDecimalAttributeType];
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];
NSError *error;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
它发生的事情似乎是获取所有对象并忽略NSPredicate。我不知道更改请求的结果类型是否对此做了什么,或者我需要使用另一个NSExpression过滤对象,或者是什么。
我的测试值是现在所有对象都将numberAsked属性设置为0,所以理论上我的最终对象数组的计数应为0,从中我指定百分比为“N / A”。但事情并没有发生。
我感谢任何帮助!
答案 0 :(得分:2)
您无法将表达式传递给setPropertiesToFetch:
。它需要一组NSPropertyDescription
个对象。我有点惊讶它并没有崩溃。
你想要这样的东西:
NSManagedObject *mo;
for (int i=0; i<5; i++) {
mo=[NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.moc];
[mo setValue:[NSNumber numberWithInt:i] forKey:@"numAttrib" ];
}
[self saveContext];
NSFetchRequest *fetch=[[NSFetchRequest alloc] init];
NSEntityDescription *testEntity=[NSEntityDescription entityForName:@"Test" inManagedObjectContext:self.moc];
[fetch setEntity:testEntity];
NSDictionary *propDict=[testEntity propertiesByName];
[fetch setPropertiesToFetch:[NSArray arrayWithObject:[propDict valueForKey:@"numAttrib"]]];
NSArray *fetchReturn=[self performFetch:fetch];//<-- my custom boilerplate
NSLog(@"fetchReturn=%@",fetchReturn);
id theAvg=[fetchReturn valueForKeyPath:@"@avg.numAttrib"];
NSLog(@"theAvg=%f",[theAvg floatValue]);
...打印:
fetchReturn=(
"<NSManagedObject: 0x5d2fae0> (entity: Test; id: 0x5d0c310 <x-coredata://384EFAF2-1921-4CB0-85B2-402DBA145615/Test/p1> ; data: {\n numAttrib = 3;\n})",
"<NSManagedObject: 0x5d35df0> (entity: Test; id: 0x5d34480 <x-coredata://384EFAF2-1921-4CB0-85B2-402DBA145615/Test/p2> ; data: {\n numAttrib = 1;\n})",
"<NSManagedObject: 0x5d33890> (entity: Test; id: 0x5d31810 <x-coredata://384EFAF2-1921-4CB0-85B2-402DBA145615/Test/p3> ; data: {\n numAttrib = 2;\n})",
"<NSManagedObject: 0x5d36d10> (entity: Test; id: 0x5d0dfa0 <x-coredata://384EFAF2-1921-4CB0-85B2-402DBA145615/Test/p4> ; data: {\n numAttrib = 4;\n})",
"<NSManagedObject: 0x5d38f00> (entity: Test; id: 0x5d302a0 <x-coredata://384EFAF2-1921-4CB0-85B2-402DBA145615/Test/p5> ; data: {\n numAttrib = 0;\n})"
)
theAvg=2.000000
如果你想减轻重量。您可以添加:
[fetch setResultType:NSDictionaryResultType];
...返回一个单键字典数组,如下所示:
fetchReturn=(
{
numAttrib = 2;
},
{
numAttrib = 0;
},
{
numAttrib = 4;
},
{
numAttrib = 1;
},
{
numAttrib = 3;
}
)
float=2.000000