NSPredicate过滤器用于多对多关系

时间:2011-09-29 04:40:09

标签: objective-c ios cocoa-touch core-data nspredicate

我仍然很擅长使用NSPredicate,但我遇到了一个有点复杂的问题,而且我不太确定解决方案的最佳方法。

我正在尝试为名为Instrument的实体构建一个过滤器,该过滤器可以与许多过程一起使用。反过来,程序与一种或多种疾病有关。疾病与许多程序有关,仪器可用于多个程序。换句话说,我有以下多对多关系:

Instruments <-> Procedures <-> Diseases

我想做的是使用Disease.title过滤仪器。在一个简单而神奇的世界里,这就像

一样简单
//where predicate is used on the Instruments array
[NSPredicate predicateWithFormat:@"(procedures.diseases.title == %@)", diseaseTitleString];

逐步完成这个(有一些错别字和错误),我发现过滤器知道过程和疾病的字段足以告诉我“疾病类型”不是程序上的字段,而“名称”是不是疾病领域。 Naivety让我希望这个简单的谓词能起作用。

我一无所获。

我也尝试使用(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设计的更好用途吗?

1 个答案:

答案 0 :(得分:2)

在上面的谓词中,将double equals替换为单个equals。还要添加“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];

最后,创建“and”或“or”谓词,例如:

 NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];