2012-04-13 114 views
13

如何使用NSPredicate的多個條件?NSPredicate中的多個條件

我正在使用這個,但沒有得到任何返回的數組中。

NSPredicate *placePredicate = [NSPredicate predicateWithFormat:@"place CONTAINS[cd] %@ AND category CONTAINS[cd] %@ AND ((dates >= %@) AND (dates <= %@)) AND ((amount >= %f) AND (amount <= %f))",placeTextField.text,selectedCategory,selectedFromDate,selectedToDate,[amountFromTextField.text floatValue],[amountToTextField.text floatValue]]; 

NSArray *placePredicateArray = [dataArray filteredArrayUsingPredicate:placePredicate]; 

NSLog(@"placePredicateArray %@", placePredicateArray); 

有時數量和類別可能爲空。我應該如何構建NSPredicate

回答

13

我會傾向於處理這一塊零碎。也就是說,

placePredicate = [NSPredicate predicateWithFormat:@"place CONTAINS[cd] %@",placeTextField.text]; 
NSMutableArray *compoundPredicateArray = [ NSMutableArray arrayWithObject: placePredicate ]; 

if(selectedCategory != nil) // or however you need to test for an empty category 
    { 
    categoryPredicate = [NSPredicate predicateWithFormat:@"category CONTAINS[cd] %@",selectedCategory]; 
    [ compoundPredicateArray addObject: categoryPredicate ]; 
    } 

// and similarly for the other elements. 

請注意,我不甚至懶得把入陣的謂詞類別(或其他任何東西)當我知道沒有一個。

// Then 
    NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: 
            compoundPredicateArray ]; 

如果我是打算做了很多,我不會使用格式的方法,但保持周圍的基石,只是改變用途之間的任何變化。

+0

+1這個評論'/或者,但是你需要測試一個空的類別'真的幫助我..謝謝! :) – 0yeoj 2016-02-11 11:05:54

29

您可以使用其他NSPredicate對象和NSCompoundPredicate

喜歡的東西建立你placesPredicate:現在

NSPredicate *p1 = [NSPredicate predicateWithFormat:@"place CONTAINS[cd] %@", placeTextField.text]; 
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"category CONTAINS[cd] %@", selectedCategory]; 
NSPredicate *p3 = [NSPredicate predicateWithFormat:@"(dates >= %@) AND (dates <= %@)", selectedFromDate,selectedToDate]; 
NSPredicate *p4 = [NSPredicate predicateWithFormat:@"(amount >= %f) AND (amount <= %f)", [amountFromTextField.text floatValue],[amountToTextField.text floatValue]]; 

NSPredicate *placesPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[p1, p2, p3, p4]]; 

,如果你缺少類別,例如,你可以只使用一個虛擬YES謂詞來代替它:

NSPredicate *p2; 
if (selectedCategory) { 
    p2 = [NSPredicate predicateWithFormat:@"category CONTAINS[cd] %@", selectedCategory]; 
} else { 
    p2 = [NSPredicate predicateWithBool:YES] 
} 
+0

謝謝。這對我幫助很大。謝謝 – 2012-04-13 12:35:59

+0

但是如何從NSPredicate中獲取數組? – 2012-04-13 12:53:03

+0

如果您需要獲取用於創建化合物的謂詞數組,請使用NSCompoundPredicate的'subpredicates'屬性。你還應該仔細看看@ DRVic的答案 - 他隨着他的發展動態地創建謂詞數組 - 這樣會更有效一些,因爲他不需要包含任何「YES」謂詞,但這意味着你不需要' t很容易知道哪個謂詞位於子預測數組中的哪個索引處。 – deanWombourne 2012-04-13 13:19:40

0
Suppose a class Person with attributes "name", "age", "income" 

"personArray" is array of class Person 

NSPredicate *mypredicate = [NSPredicate predicateWithBlock:^BOOL(personObj Person, NSDictionary *bindings) { 
    NSNumber *age = personObj.age; 
    String *name = personObj.name; 
    NSNumber *income = personObj.income 
    BOOL result = (age > 20 && name == "Stack" && income >40000); 
    return result; 
}]; 

NSArray *filteredArray = [personArray filteredArrayUsingPredicate: mypredicate]; 

如需進一步,你可以閱讀這篇文章Array Filter Using Blocks

在斯威夫特

let filterArray = personArray.filter 
      { person in 
      let age = personObj.age; 
      let name = personObj.name; 
      let income = personObj.income 
      BOOL result = (age > 20 && name == "Stack" && income >40000); 
      return result; 
     }