用于多对多对多关系的 NSPredicate 过滤器

发布于 2024-12-07 09:59:54 字数 1251 浏览 0 评论 0原文

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

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

Instruments <-> Procedures <-> Diseases

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

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

一步一步地逐步执行(有一些拼写错误和错误命名)一样简单,我发现过滤器知道程序和疾病的字段足以告诉我“疾病类型”不是程序字段,而“名称”不是疾病字段。天真让我希望这个简单的谓词能够起作用。

我什么也没得到。

我也尝试过使用 (ALL procedure.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 设计的更好用法?

I'm still fairly new to using NSPredicate, but I've got a somewhat complicated issue and I'm not quite sure the best way to go about a solution.

I'm attempting to build a filter for an entity called Instrument, which can be used with many Procedures. Procedures, in turn, are related to one or more Diseases. Diseases are related to many Procedures, and Instruments can be used in more than one Procedure. In other words, I have the following many-to-many-to-many relationship:

Instruments <-> Procedures <-> Diseases

What I would like to do is filter Instruments using Disease.title. In a simple and magical world, this would be as simple as

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

Stepping through this piece by piece (with a few typos and misnamings), I found that the filter knows the fields of Procedures and Diseases enough to tell me that "diseaseTypes" is not a field on procedures, and "name" is not a field on diseases. Naivety led me to hoping that this simple predicate would work.

I get nothing.

I've also tried using (ALL procedures.diseases.title == %@), but that doesn't work either.

I've seen some things about sub-predicates, but nothing that really sticks out to me as something that works or makes a lot of sense to me.

Basically I want to get the list:

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];
        }
      }
    }
  }
}

Right now, I'm using this method to get an array that I can filter based on other predicates, and it's working fine, but it's ugly and I feel like there is a better, cleaner way do filter this. Can anyone help educate me on the finer uses of NSPredicate design?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

若能看破又如何 2024-12-14 09:59:54

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

On the predicate you have above, replace the double equals with a single equals. Also add an "ANY" clause. Finally, remove the parentheses. So you will have:

[NSPredicate predicateWithFormat:@"ANY procedures.diseases.title = %@", diseaseTitleString];

In general, I find a good way to handle complex predicates is to build them up using sub-predicates.

So, you start with:

        NSMutableArray *subpredicates = [NSMutableArray array];

Then bit by bit you add your subpredicates:

[subpredicates addObject:
    [NSPredicate predicateWithFormat:@"ANY procedures.diseases.title = %@",
         diseaseTitleString]]

[subpredicates addObject:anotherPredicate etc];

Finally, create your "and" or "or" predicate, for example:

 NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文