在NSPredicate中组合“AND”和“OR”条件 [英] Combining 'AND' and 'OR' Condition in NSPredicate
问题描述
再次需要更多帮助来构建我的NSPredicates:(
类别
{
name: string
subs< - >> SubCategory
}
SubCategory
{
name:string
numbervalue:NSNumber
}
我想知道如何使用 AND 和 OR 。
例如,我想返回每个具有名称为category_name的类别, valueA OR valueB。
我尝试过各种可能的谓词构造函数组合,
这是我迄今为止最好的尝试。
NSPredicate * predicate = [NSPredicate predicateWithFormat @(name ==%@)AND(ANY subs.numbervalue ==%@ OR ANY subs.numbervalue ==%@),@aname,value1,value2];
编辑1
第二次尝试。对'numbervalue'的过滤仍然无效。
NSNumber valueA = [NSNumber numberWithInt:20];
NSNumber valueA = [NSNumber numberWithInt:90];
NSArray * arr = [NSArray arrayWithObject:valueA,valueB,nil];
predicate = [NSPredicate predicateWithFormat:@(name ==%@)AND(ANY subs.numbervalue IN%@),@aname,arr];
编辑2
1)使用这个结果在整个集合中返回,即使只有一个项目在集合中有值。
predicate = [NSPredicate predicateWithFormat:@(ANY subs.numbervalue IN%@),arr];
2)使用此结果导致同样的问题,即使只返回1的匹配。
谓词= [NSPredicate predicateWithFormat:@((SUBQUERY(subs,$ x,$ x.numbervalue = =%@ or $ x.numbervalue ==%@)。@ count> 0),value1,value2];
b $ b也使用最简单的版本导致相同的问题....我没有注意到这个早。
NSPredicate * predicate = [NSPredicate predicateWithFormat @(ANY subs.numbervalue ==%@,valueA];
$ b类别与子类别具有一对多关系,并表示为子类别的NSSet。
每个子类别都有一个名为numbervalue的属性。
编辑3
要测试我有2个类别
每个都有1到10的数字值;
使用此代码,每个类别都返回所有10个订阅。
预期结果是返回的两个类别,每个类别只有2个。
我已经找出了所有对象,数据是正确的。问题是我不能返回已过滤的子类别。
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext * context = [[DataSource sharedDataSource] managedObjectContext];
NSEntityDescription * entity = [NSEntityDescription entityForName:@CategoryinManagedObjectContext:context];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@nameascending:YES];
NSArray * sortDescriptors = [NSArray arrayWithObjects:sortDescriptor,nil];
NSPredicate *谓词;
NSNumber * a = [NSNumber numberWithFloat:1];
NSNumber * b = [NSNumber numberWithFloat:2];
predicate = [NSPredicate predicateWithFormat:@(SUBQUERY(subs,$ x,$ x.numbervalue ==%@ or $ x.numbervalue ==%@)。@ count> 0),a,b] ;
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:sortDescriptors];
NSError * error = nil;
[NSFetchedResultsContoller deleteCacheWithName:nil];
NSFetchedResultsController * aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@namecacheName:@Master];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
if(![self.fetchedResultsController performFetch:& error]){
NSLog(@未解析的错误%@,%@,错误,[error userInfo] );
abort();
}
解决方案使用
SUBQUERY
。[NSPredicate predicateWithFormat @ %@)AND(SUBQUERY(subs,$ x,$ x.numbervalue ==%@ or $ x.numbervalue ==%@)。@ count> 0),@aname,value1,value2];
尝试一下,让我知道。
另一个解决方案可以是抓取整个集合
subs
,然后使用谓词过滤检索的集合,以检查元素是否与value1
或value2
。
希望它有帮助。
编辑
如果您遵循 Eimantas 建议,请确保创建正确的数组:
NSNumber valueA = [NSNumber numberWithInt:20];
NSNumber valueB = [NSNumber numberWithInt:90];
NSArray * arr = [NSArray arrayWithObjects:valueA,valueB,nil];
Back again needing more help with constructing my NSPredicates :(
Category { name:string subs<-->>SubCategory } SubCategory { name:string numbervalue:NSNumber }
I would like to know how to create a predicate with AND and OR.
For example, I would like to return every Category with name == "category_name" that also has a subcategory with a numbervalue of "valueA" OR "valueB".
I've tried every possible combination of predicate constructors I could come up with but I just cant get it to work.
This is my best attempt so far.
NSPredicate *predicate=[NSPredicate predicateWithFormat@"(name== %@) AND (ANY subs.numbervalue==%@ OR ANY subs.numbervalue==%@)", @"aname", value1, value2];
Edit 1
Second attempt. The filtering on the 'numbervalue' is still not working.
NSNumber valueA=[NSNumber numberWithInt:20]; NSNumber valueA=[NSNumber numberWithInt:90]; NSArray *arr=[NSArray arrayWithObject:valueA,valueB,nil]; predicate=[NSPredicate predicateWithFormat:@"(name==%@)AND(ANY subs.numbervalue IN %@)",@"aname",arr];
Edit 2
I've tried filtering just by numberValue and have left the name out alltogether.
1) using this results in the entire set being returned even if only 1 item in the set has the value.
predicate=[NSPredicate predicateWithFormat:@"(ANY subs.numbervalue IN %@)",arr];
2) Using this results in the same problem, every item in the set being returned even if only 1 of them matches.
predicate=[NSPredicate predicateWithFormat:@"((SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@).@count > 0)", value1, value2];
Also using the simplest version results in the same problem.... I didnt notice this earlier.
NSPredicate *predicate=[NSPredicate predicateWithFormat@"(ANY subs.numbervalue==%@ ,valueA];
So I think I have my problem narrowed down.
Category is an Entity. SubCategory is an Entity.
Category has a one to many relationship with SubCategory and is represented as an NSSet of SubCategory.
Each SubCategory has an attribute named numbervalue.
Edit 3
To test I have 2 Categorys. Both Categories have 10 subs, each with a numbervalue of 1 -10;
Using this code both categories are returned along with all 10 subs for each.
Expected result is both categories returned , each with just 2 subs.
I've traced out all my objects and the data is correct. The problem is I cant return a category that has filtered subs.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSManagedObjectContext *context=[[DataSource sharedDataSource]managedObjectContext]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:context]; [fetchRequest setEntity:entity]; [fetchRequest setFetchBatchSize:20]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; NSPredicate *predicate; NSNumber *a=[NSNumber numberWithFloat:1]; NSNumber *b=[NSNumber numberWithFloat:2]; predicate=[NSPredicate predicateWithFormat:@"(SUBQUERY(subs,$x,$x.numbervalue==%@ or $x.numbervalue==%@).@count> 0)",a,b]; [fetchRequest setPredicate:predicate]; [fetchRequest setSortDescriptors:sortDescriptors]; NSError *error = nil; [NSFetchedResultsContoller deleteCacheWithName:nil]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"name" cacheName:@"Master"]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; if (![self.fetchedResultsController performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); }
解决方案I'll do the following using a
SUBQUERY
.[NSPredicate predicateWithFormat@"(name == %@) AND (SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@).@count > 0)", @"aname", value1, value2];
Try it and let me know.
Another solution could be to grab the whole collection
subs
and then filter the retrieved set with a predicate to check if elements match forvalue1
orvalue2
.Hope it helps.
Edit
If you follow Eimantas suggestion make to sure to create the right array:
NSNumber valueA = [NSNumber numberWithInt:20]; NSNumber valueB = [NSNumber numberWithInt:90]; NSArray *arr = [NSArray arrayWithObjects:valueA, valueB, nil];
这篇关于在NSPredicate中组合“AND”和“OR”条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!