【问题标题】:NSPredicate with multiple comparisons for one query stringNSPredicate 对一个查询字符串进行多重比较
【发布时间】:2011-09-24 03:14:17
【问题描述】:

我想知道是否有一种方法可以简化一个 NSPredicate,它接受一个查询字符串来处理多个比较目标。我正在为同一查询字符串搜索核心数据实体的多个属性。我当前的查询看起来像这样......

[NSPredicate predicateWithFormat:@"(attributeA contains[cd] %@) OR (attributeB contains[cd] %@) OR (attributeC contains[cd] %@)", searchString, searchString, searchString];

请注意,这可以完美运行,但看起来确实有点难看。尤其是searchString, searchString, searchString 部分。任何关于我如何简化它的提示都会很棒!

谢谢!

【问题讨论】:

    标签: objective-c ios nspredicate


    【解决方案1】:

    您可以像这样将 NSCompoundPredicate 用于您的 OR & AND 操作。

    Obj-C - 或

    // OR Condition //
    
    NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"];
    NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"];
    NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[predicate1, predicate2]];
    

    Obj-C - 与

    NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"];
    NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"];
    NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[predicate1, predicate2]];
    

    斯威夫特 - 或

    let predicate1:NSPredicate = NSPredicate(format: "X == 1")
    let predicate2:NSPredicate = NSPredicate(format: "Y == 2")
    let predicate:NSPredicate  = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1,predicate2] )
    

    斯威夫特 - 与

    let predicate1:NSPredicate = NSPredicate(format: "X == 1")
    let predicate2:NSPredicate = NSPredicate(format: "Y == 2")
    let predicate:NSPredicate  = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2] )
    

    Swift 3 - 或

        let predicate1 = NSPredicate(format: "X == 1")
        let predicate2 = NSPredicate(format: "Y == 2")
        let predicateCompound = NSCompoundPredicate.init(type: .or, subpredicates: [predicate1,predicate2])
    

    Swift 3 - 与

        let predicate1 = NSPredicate(format: "X == 1")
        let predicate2 = NSPredicate(format: "Y == 2")
        let predicateCompound = NSCompoundPredicate.init(type: .and, subpredicates: [predicate1,predicate2])
    

    【讨论】:

    • 同时包含 Objective-C 和 Swift 代码可以提高这个答案的质量。
    【解决方案2】:

    你可以这样做:

    NSPredicate *p = [NSPredicate predicateWithFormat:@"attributeA contains[cd] $A OR attributeB contains[cd] $A or attributeC contains[cd] $A"];
    NSDictionary *sub = [NSDictionary dictionaryWithObject:searchString forKey:@"A"];
    p = [p predicateWithSubstitutionVariables:sub];
    

    或者你可以做一些更奇怪的事情,像这样:

    - (NSPredicate *)buildOrPredicate:(NSDictionary *)stuff {
      NSMutableArray *subs = [NSMutableArray array];
      for (NSString *key in stuff) {
        NSString *value = [stuff objectForKey:stuff];
        NSPredicate *sub = [NSPredicate predicateWithFormat:@"%K contains[cd] %@", key, value];
        [subs addObject:sub];
      }
      return [NSCompoundPredicate orPredicateWithSubpredicates:subs];
    }
    

    然后调用它:

    NSDictionary *stuff = [NSDictionary dictionaryWithObjectsAndKeys:
                           searchString, @"attributeA",
                           searchString, @"attributeB",
                           searchString, @"attributeC",
                           nil];
    NSPredicate *p = [self buildOrPredicate:stuff];
    

    我能想到的唯一可行的方法是尝试在谓词格式中使用位置指定。但是,我不知道解析器是否以与+stringWithFormat: 相同的方式识别它们:

    NSPredicate *p = [NSPredicate predicateWithFormat:@"attributeA contains[cd] %1$@ OR attributeB contains[cd] %1$@ or attributeC contains[cd] %1$@", searchString];
    

    【讨论】:

    • 谢谢,但所有 3 个都更长。我对使用速记没有任何问题,即使它可能很难阅读。我一直在寻找一种既短又不需要在其中包含 3 次“searchString”(如果可能的话)的解决方案!
    • 不,解析器似乎不理解位置说明符。 :(顺便说一句,我发现了这个问题的一个副本:stackoverflow.com/questions/6305940/… 那里有类似的答案。
    猜你喜欢
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    相关资源
    最近更新 更多