【问题标题】:Can I pass operators into an NSPredicate via the format string?我可以通过格式字符串将运算符传递给 NSPredicate 吗?
【发布时间】:2013-05-17 20:14:23
【问题描述】:

我正在尝试创建以下谓词

[NSPredicate predicateWithFormat:@"name != %@ AND date %@ %@", varName, operator, varDate]

其中varNamevarDate 分别是NSString 和NSDate 对象。 operator 变量声明如下:

NSString *operator = (direction == kPageDirectionForward) ? @">" : @"<";

基本上我想在创建谓词时保存几行。我知道我可以根据 direction 的值创建不同的谓词,但这个用例让我思考。

现在这个当前的方法崩溃了,所以我认为它不可能。我想知道是否还有其他人有运气。

【问题讨论】:

    标签: ios core-data nspredicate predicate


    【解决方案1】:

    您可以通过NSComparisonPredicateNSCompoundPredicate 的组合来实现此目的:

    // First part: name != <varName>
    NSPredicate *p1 = [NSPredicate predicateWithFormat:@"name != %@", varName];
    
    // Second part: date <op> <varDate>
    NSExpression *lexp = [NSExpression expressionForKeyPath:@"date"];
    NSExpression *rexp = [NSExpression expressionForConstantValue:varDate];
    NSPredicateOperatorType op = (direction == kPageDirectionForward) ? NSGreaterThanPredicateOperatorType : NSLessThanOrEqualToPredicateOperatorType;
    NSPredicate *p2 = [NSComparisonPredicate predicateWithLeftExpression:lexp
                                                         rightExpression:rexp
                                                                modifier:0
                                                                    type:op
                                                                 options:0];
    // predicate = <p1> AND <p2>
    NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[p1, p2]];
    

    【讨论】:

    • 好的,这不会像你说的那样“节省几行”,但无论如何如何在运行时动态创建谓词可能很有趣。
    • 试图节省代码行,所以我可能不会使用它,但我很高兴我知道它是可能的。如果您想动态创建谓词,这看起来是正确的答案
    【解决方案2】:

    我意识到这与 op 关于使用不同谓词字符串的声明没有根本不同,但您可以动态构建谓词字符串:

    NSString *operator = (direction == kPageDirectionForward) ? @">" : @"<";
    
    NSMutableString * predicateString = [NSMutableString stringWithString: @"name != %@ AND date "];
    [predicateString appendString: operator];
    [predicateString appendString: @" %@"];
    [NSPredicate predicateWithFormat: predicateString, varName, varDate];
    // should return valid predicate: @"name != %@ AND date < %@"
    

    作为一个稍微奇怪的例子,只要您查询 nsobjects,这应该可以工作:

    NSString * predicateString = [NSString stringWithFormat: @"name != %@ AND date %@ %@", @"%@", operator, @"%@"];
    [NSPredicate predicateWithFormat: predicateString, varName, varDate];
    

    【讨论】:

      【解决方案3】:

      确实有更有效的方法来做到这一点:

      NSString *dateOperator = (direction == kPageDirectionForward) ? @">" : @"<";
      NSString *stringPredicate=[NSString stringWithFormat:@"%%K != %%@ AND %%K %@ %%@", dateOperator];
      
      NSPredicate *yourPredicate=[NSPredicate stringPredicate argumentArray:@[@"name",varName,@"date",varDate]];
      

      【讨论】:

      • 这真的是最明确最简洁的回答了。
      【解决方案4】:

      您不能这样做,因为格式字符串与提供的参数不同,因为在处理格式字符串以生成有效且可解析的谓词字符串时,提供的参数将被引用。

      【讨论】:

      • 必须等待 6 分钟才能接受此答案。抱歉,如果我忘记了,感谢您的回复更有意义。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 1970-01-01
      相关资源
      最近更新 更多