再次需要更多帮助来构建我的 NSPredicates :(
Category
{
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
第二次尝试。对“数值”的过滤仍然无效。
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
我试过仅按 numberValue 进行过滤,并将名称完全排除在外。
1) 使用此结果会返回整个集合,即使集合中只有 1 个项目具有该值。
predicate=[NSPredicate predicateWithFormat:@"(ANY subs.numbervalue IN %@)",arr];
2) 使用它会导致同样的问题,即使其中只有 1 个匹配,也会返回集合中的每个项目。
predicate=[NSPredicate predicateWithFormat:@"((SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@).@count > 0)", value1, value2];
同样使用最简单的版本会导致同样的问题......我之前没有注意到这一点。
NSPredicate *predicate=[NSPredicate predicateWithFormat@"(ANY subs.numbervalue==%@ ,valueA];
所以我想我的问题缩小了。
类别是一个实体。
子类别是一个实体。
Category 与 SubCategory 是一对多的关系,表示为 SubCategory 的 NSSet。
每个 SubCategory 都有一个名为 numbervalue 的属性。
编辑 3
为了测试,我有 2 个类别。
两个类别都有 10 个子项,每个子项的数值为 1 -10;
使用此代码返回两个类别以及每个类别的所有 10 个子项。
预期结果是返回两个类别,每个类别只有 2 个子项。
我已经找出了我所有的对象并且数据是正确的。问题是我无法返回已过滤子项的类别。
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();
}
最佳答案
我将使用 SUBQUERY
执行以下操作。
[NSPredicate predicateWithFormat@"(name == %@) 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];
关于ios - 在 NSPredicate 中结合 'AND' 和 'OR' 条件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10317692/