2010-08-27 42 views
2

我有一个视图,我希望获得“百分比”属性的平均值,而无需将所有对象(及其他属性)从核心数据加载到内存中。我已经发现如何在苹果的文档中做到这一点,但问题是我想限制百分比被平均化的对象为具有另一个名为“numberAsked”的属性大于0的对象。我认为这是我可以做的事情与NSPredicate。在核心数据中使用NSPredicate过滤setPropertiesToFetch?

以下是我有:

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或者什么来过滤对象。

我的测试值是,现在所有的对象都有数字被设置为0的属性,所以理论上我的最终对象数组应该有0的计数,从那里我会指定百分比的“N/A”。但是这并没有发生。

我感谢任何帮助!

回答

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 
+0

我不知道这是否是我想要的东西,或者如果我很清楚... 我的代码与下面的Apple代码类似。我将NSExpressionDescriptions(不是NSExpressions)的数组传递给setPropertiesToFetch :.该代码位于“获取特定值”下: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html#//apple_ref/doc/uid/TP40002484- SW6 我得到的百分比属性的平均值就好了,只是我不一定要平均所有的百分比 - 只是该对象的另一个属性(numAsked)> 0的对象的百分比。 – Kevin 2010-08-27 20:12:55

相关问题