【问题标题】:NSPredicate filter for many-to-many-to-many relationships用于多对多关系的 NSPredicate 过滤器
【发布时间】:2011-09-29 04:40:08
【问题描述】:

我对使用 NSPredicate 还很陌生,但我遇到了一个有点复杂的问题,我不太确定解决方案的最佳方法。

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

Instruments <-> Procedures <-> Diseases

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

//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 设计的更精细用途?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 这里有一些很好的提示,但该谓词仍然返回一个空数组。我的其他子谓词工作正常,但这个多对多的仍然不工作,但应该等同于我上面代码中的循环构建集合。 [instrumentFilters addObject:[NSPredicate predicateWithFormat:@"ANY procedures.diseases.title = %@", filterValue]]; 然后我做了一个与其他过滤器一起工作的复合。我还有什么遗漏吗?
    • 如果在没有 and 复合的情况下运行它会发生什么?
    • 仅使用该谓词(无复合词)运行过滤器仍然不会返回任何内容。 :(
    • 嗯。你能打开 .sqlite 文件并运行等效的 SQL 查询吗?剪切并粘贴疾病标题。另外,确认没有尾随空格等。
    • @MaxMacLeod 嗨,Max,很好的答案,也许你能帮帮我。我的关系 Object>addresses>phones 我需要检查 phones.tel 是否包含我的电话号码,我尝试 [NSPredicate predicateWithFormat:@"ANY addresses.phones.tel = %@", searchWord] 但我收到错误 @ 987654327@,你能给点建议吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 2014-08-20
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多