2012-04-13 10 views
13

Cách sử dụng nhiều điều kiện với NSPredicate?Nhiều điều kiện trong NSPredicate

Tôi đang sử dụng nhưng không nhận được gì trong mảng được trả về.

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

Số tiền và loại có thể trống đôi khi. Tôi nên xây dựng NSPredicate như thế nào?

Trả lời

13

Tôi có xu hướng xử lý mô hình này một phần. Tức là,

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. 

Lưu ý rằng tôi thậm chí không bận tâm đến vị ngữ của danh mục (hoặc bất kỳ điều gì khác) khi tôi biết không có.

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

Và nếu tôi định làm điều đó rất nhiều, tôi sẽ không sử dụng phương pháp định dạng, nhưng giữ xung quanh khối xây dựng và thay đổi bất kỳ thay đổi nào giữa các lần sử dụng.

+0

+1 cho nhận xét này '// hoặc tuy nhiên bạn cần kiểm tra một danh mục trống' thực sự đã giúp tôi .. cảm ơn! :) – 0yeoj

29

Bạn có thể xây dựng placesPredicate bạn sử dụng NSPredicate các đối tượng khác và lớp NSCompoundPredicate

Cái gì như:

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

Bây giờ, nếu bạn đang thiếu loại ví dụ bạn chỉ có thể sử dụng một hình nộm YES ngữ để thay thế nó:

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

Cảm ơn bạn. Nó đã giúp tôi rất nhiều. Cảm ơn –

+0

Nhưng làm thế nào để có được một mảng từ NSPredicate? –

+0

Nếu bạn cần lấy mảng các biến vị ngữ được sử dụng để tạo ra hợp chất, hãy sử dụng thuộc tính 'subpredicates' của' NSCompoundPredicate'. bạn cũng nên xem xét câu trả lời của @ DRVic - anh ta tạo ra một loạt các biến vị ngữ động như anh ta đi - điều này hiệu quả hơn một chút bởi vì anh ta không cần phải bao gồm bất kỳ vị từ 'YES' nào nhưng điều đó có nghĩa là bạn don ' t biết vị ngữ nào là ở đó chỉ số trong mảng subpredicates dễ dàng. – deanWombourne

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

Để biết thêm bạn có thể đọc bài viết này Array Filter Using Blocks

Trong Swift

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; 
     }