使用预先构建的字符串创建谓词

时间:2011-05-11 15:50:20

标签: nspredicate

有没有办法直接从预先格式化的字符串创建一个nspredicate而不调用predicateWithFormat?最后的字符串看起来像:

(inpatient=1) AND (dischargedate!=<null>) AND ((attending=SMITH) OR (admitting=SMITH) OR (consulting contains[cd] SMITH) OR (attending=JONES) OR (admitting=JONES) OR (consulting contains[cd] JONES))

    NSMutableString *preds = [[NSMutableString alloc] initWithString:@""];

    NSArray *provs = [self.providerCode componentsSeparatedByString:@"|"];
    for (NSString *prov in provs) {
        [preds appendFormat:@" (attending=%@) OR (admitting=%@) OR (consulting contains[cd] %@) ", prov, prov, prov];
    }
    NSString *final = [NSString stringWithFormat:@"(inpatient=%@) AND (dischargedate!=%@) AND (%@)", [NSNumber numberWithBool: self.inpatients], [NSNull null], preds];

    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:final]];

1 个答案:

答案 0 :(得分:0)

是的,你可以,但你需要稍微修改格式字符串。

而不是:

[preds appendFormat:@" (attending = %@)", prov];

你需要这样做:

[preds appendFormat:@" (attending = '%@')", prov];

请注意%@修饰符周围使用单引号。这就是谓词知道它是一个恒定值的方式。

但是,即使你走这条路线,你仍然会使用你想要避免的predicateWithFormat:。您也可能在格式字符串中使用NSNull时遇到问题。

我建议做更像这样的事情:

NSArray *provs = [self.providerCode componentsSeparatedByString:@"|"];

NSMutableArray *providerPredicates = [NSMutableArray array];
NSPredicate *template = [NSPredicate predicateWithFormat:@"attending = $prov OR admitting = $prov OR consulting CONTAINS[cd] $prov"];
for (NSString *prov in provs) {
  NSDictionary *substitutions = [NSDictionary dictionaryWithObject:prov forKey:@"prov"];
  NSPredicate *p = [template predicateWithSubstitutionVariables:substitutions];
  [providerPredicates addObject:p];
}

NSPredicate *final = [NSPredicate predicateWithFormat:@"inpatient = 1 AND dischargedate != nil"];

if ([providerPredicates count] > 0) {
  NSPredicate *providers = nil;
  if ([providerPredicates count] > 1) {
    providers = [NSCompoundPredicate orPredicateWithSubpredicates:providerPredicates];
  } else {
    providers = [providerPredicates objectAtIndex:0];
  }

  final = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:final, providers, nil]];
}

这是使用几个不同的整洁的东西:

  1. 谓词变量。您解析格式字符串@"attending = $prov OR admitting = $prov OR consulting CONTAINS[cd] $prov"一次,然后每次有不同的提供商时,只需用新值代替$prov
  2. 构造复合谓词。您可以在NSCompoundPredicate上使用某些类方法将多个谓词转换为单个分组ORAND谓词。