2011-09-24 42 views
3

我想知道是否有一種方法可以簡化爲多個比較目標提供單個查詢字符串的NSPredicate。我正在爲相同的查詢字符串搜索核心數據實體的多個屬性。我目前的查詢看起來像這樣...針對一個查詢字符串進行多重比較的NSPredicate

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

請注意,這工作完美,但它確實看起來有點難看。尤其是searchString, searchString, searchString部分。任何關於如何簡化這一點的提示都會很棒!

謝謝!

回答

3

你可以這樣做:

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] %[email protected] OR attributeB contains[cd] %[email protected] or attributeC contains[cd] %[email protected]", searchString]; 
+0

謝謝,但那些所有3個較長。即使閱讀起來很困難,我也沒有使用簡寫的問題。我一直在尋找一個短小的解決方案,並且不需要在那裏搜索「searchString」3次(如果可能的話)! – mjisrawi

+0

@mjisrawi增加了另一個* *可能會起作用的選項。 –

+0

不,解析器似乎並不瞭解位置說明符。 :(順便說一句,我發現這個問題的重複:http://stackoverflow.com/questions/6305940/shorter-way-to-write-nspredicate-format-string-for-testing-multiple-properties那裏有類似的答案。 – mjisrawi

3

您可以使用NSCompoundPredicate您或&和操作是這樣的。

對象 - - OR

// OR Condition // 

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

對象 - - 和

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

斯威夫特 - OR

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]) 

斯威夫特3 - 或

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

斯威夫特3 - 和

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

包括Objective-C和Swift代碼都提高了這個答案的質量。 – ElmerCat

+0

thx :)希望這可以幫助每個人 –

相關問題