NSPredicate:取一种
我想为NSFetchRequest
的对象创build一个NSFetchRequest
:
Object
是具有attribute
color
Car
。 我有四辆车:
car1.color = red car2.color = red car3.color = blue car4.color = green
我想创build一个NSPredicate
,为每种颜色只select一辆车(它select哪辆车并不重要。
我怎样才能做到这一点?
事实上,我正在寻找类似于SQL中的DISTINCT
东西
核心数据支持获取不同的值。 苹果甚至提供了示例代码: http : //developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/CoreDataSnippets/Articles/fetchExpressions.html
从该页面:
获取不同的值
要通过给定实体的所有实例获取特定属性的唯一值,请使用方法setReturnsDistinctResults :(并将YES作为参数)configuration一个提取请求。 您还指定提取应该返回字典而不是托pipe对象,以及要提取的属性的名称。
Swift 2.0
let context:NSManagedObjectContext! = <#Get the context#> let entity = NSEntityDescription.entityForName( "<#Entity name#>", inManagedObjectContext:context ) let request = NSFetchRequest() request.entity = entity request.resultType = .DictionaryResultType request.returnsDistinctResults = true request.propertiesToFetch = [ "<#Attribute name#>" ] var objects:[[String:AnyObject]]? do { try objects = context.executeFetchRequest( request ) } catch { // handle failed fetch }
OBJ-C
NSManagedObjectContext *context = <#Get the context#>; NSEntityDescription *entity = [NSEntityDescription entityForName:@"<#Entity name#>" inManagedObjectContext:context]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:entity]; [request setResultType:NSDictionaryResultType]; [request setReturnsDistinctResults:YES]; [request setPropertiesToFetch:@[@"<#Attribute name#>"]]; // Execute the fetch. NSError *error = nil; id requestedValue = nil; NSArray *objects = [context executeFetchRequest:request error:&error]; if (objects == nil) { // Handle the error. }
(一个“疑难杂症”是,结果将作为字典返回 – 如果你需要的对象,你可以做另一个获取通过ID得到他们)
你有没有尝试过使用valueForKeyPath
? 你可以在NSPredicate提供给你的数组中做类似的事情。
NSArray* distinctColors = [cars valueForKeyPath:@"@distinctUnionOfObjects.color"];
它会给你带来不同的色彩,我不知道它是不是你想要的,但是你可以用颜色来做一些类似于@Anupdas的事情:
如果您的目标是iOS 4.0或更高版本,而不是使用Core-Data SQL存储,为什么不使用predicateWithBlock:
以下将生成你想要的NSFetchRequest
。
- (NSFetchRequest*) fetchRequestForSingleInstanceOfEntity:(NSString*)entityName groupedBy:(NSString*)attributeName { __block NSMutableSet *uniqueAttributes = [NSMutableSet set]; NSPredicate *filter = [NSPredicate predicateWithBlock:^(id evaluatedObject, NSDictionary *bindings) { if( [uniqueAttributes containsObject:[evaluatedObject valueForKey:attributeName]] ) return NO; [uniqueAttributes addObject:[evaluatedObject valueForKey:attributeName]]; return YES; }]; NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:entityName]; req.predicate = filter; return req; }
然后,您可以创build一个新的方法来执行获取并返回所需的结果。
- (NSArray*) fetchOneInstanceOfEntity:(NSString*)entityName groupedBy:(NSString*)attributeName { NSFetchRequest *req = [self fetchRequestForSingleInstanceOfEntity:entityName groupedBy:attributeName]; // perform fetch NSError *fetchError = nil; NSArray *fetchResults = [_context executeFetchRequest:req error:&fetchError]; // fetch results if( !fetchResults ) { // Handle error ... return nil; } return fetchResults; }
你看起来像这样
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Car"]; [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"color == %@",@"green"]]; [fetchRequest setFetchLimit:1]; NSError *error = nil; NSArray *fetchedCars = [context executeFetchRequest:fetchRequest error:&error]; Car *car = [fetchedCars lastObject]; if(!car){ //Handle the error }
尝试这个:
NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Selected_data" inManagedObjectContext:self.managedObjectContext]; [request setEntity:entity]; NSPredicate *predicatecnName = [NSPredicate predicateWithFormat:@"countries contains[cd] %@", Countryid]; NSPredicate *predicateLn = [NSPredicate predicateWithFormat:@"languages contains[cd] %@", languageid]; NSArray *subPredicates = [NSArray arrayWithObjects:predicatecnName, predicateLn, nil]; NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates]; [request setPredicate:predicate]; NSMutableArray *sendfd=[[NSMutableArray alloc] init]; NSError *error; NSArray *array1 = [self.managedObjectContext executeFetchRequest:request error:&error]; if (array1 != nil) { for (Selected_data *sld in array1) { [sendfd addObject:sld.providers]; } } else { } return sendfd;
试试这个:
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Cars"]; NSArray *arrayValues = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; if (arrayValues.count != 0) { NSDictionary *result = [NSDictionary dictionaryWithObjects:arrayValues forKeys:[arrayValues valueForKey:@"color"]]; return [result allValues]; }