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]; }