我对使用 NSPredicate 还是很陌生,但我遇到了一个有点复杂的问题,我不太确定解决问题的最佳方法。
我正在尝试为一个名为 Instrument 的实体构建一个过滤器,它可以与许多过程一起使用。程序又与一种或多种疾病有关。疾病与许多程序有关,而仪器可以用于不止一种程序。换句话说,我有以下多对多对多关系:
Instruments <-> Procedures <-> Diseases
我想做的是使用 Disease.title 过滤 Instruments。在一个简单而神奇的世界里,这就像
//where predicate is used on the Instruments array
[NSPredicate predicateWithFormat:@"(procedures.diseases.title == %@)", diseaseTitleString];
逐条检查(有一些拼写错误和命名错误),我发现过滤器知道 Procedures 和 Diseases 的字段足以告诉我“diseaseTypes”不是 procedures 的字段,“name”是不是疾病领域。天真让我希望这个简单的谓词能起作用。
我一无所获
我也尝试过使用 (ALL procedures.diseases.title == %@)
,但这也不起作用。
我已经看到了一些关于子谓词的东西,但没有什么真正让我觉得有用或对我来说很有意义。
基本上我想得到列表:
NSArray *instruments = [[NSArray alloc] init];
for (Disease *disease in Diseases) {
if ([disease.title isEqualToString:titleString]) {
for (Procedure *procedure in disease.procedures) {
for (Instrument *instrument in procedure.instruments) {
if (![instruments containsObject:instrument]) {
[instruments addObject:instrument];
}
}
}
}
}
现在,我正在使用此方法获取一个数组,我可以根据其他谓词对其进行过滤,它工作正常,但它很丑陋,我觉得有更好、更干净的方法来过滤它。谁能帮助我了解 NSPredicate 设计的更好用途?
最佳答案
在上面的谓词中,将双等号替换为单个等号。还要添加一个“ANY”子句。最后,去掉括号。所以你将拥有:
[NSPredicate predicateWithFormat:@"ANY procedures.diseases.title = %@", diseaseTitleString];
一般来说,我发现处理复杂谓词的一个好方法是使用子谓词构建它们。
所以,你开始:
NSMutableArray *subpredicates = [NSMutableArray array];
然后一点一点地添加子谓词:
[subpredicates addObject:
[NSPredicate predicateWithFormat:@"ANY procedures.diseases.title = %@",
diseaseTitleString]]
[subpredicates addObject:anotherPredicate etc];
最后,创建您的“和”或“或”谓词,例如:
NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
关于objective-c - 用于多对多对多关系的 NSPredicate 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7592516/