Несколько NSPredicate
Я пытаюсь подготовить несколько поисков в моем объекте CoreData Рецепты. Есть параметры, по которым я хотел бы подготовить выборку.
Рецепты:
@property (nonatomic, retain) NSNumber * difficulty;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * code; //like identifier
@property (nonatomic, retain) NSNumber * prepTime;
Ингредиенты - это отдельный объект со списком ингредиентов.
Присоединить сущность содержит componentientCode, recipeCode, count.
getArrayOfJoinDataWithIngredients извлекает join и возвращает NSArray из кодов рецептов, содержащих часть входного ингредиента.
Вот мой код:
- (IBAction)callRecipeFetch:(id)sender
{
NSString *predicateString = @"";
NSArray *codes = [[NSArray alloc] init]; codes = nil;
if ([paramController.ingredientsForSearchArray count] > 0) {
NSMutableArray *ingredientsArray = [[NSMutableArray alloc] init];
for (Ingredients *ingredient in paramController.ingredientsForSearchArray) {
[ingredientsArray addObject:ingredient.code];
}
MainTabController *mainTabController = [[MainTabController alloc] init];
codes = [mainTabController getArrayOfJoinDataWithIngredients:ingredientsArray];
NSString *ingrSet = [NSString stringWithFormat:@"(code IN %@)", codes];
predicateString = [predicateString stringByAppendingString:ingrSet];
}
NSString *diff;
if ([predicateString isEqualToString:@""]) {
diff = [NSString stringWithFormat:@"(difficulty <= %d)", paramController.diff.selectedSegmentIndex + 1];
}
else diff = [NSString stringWithFormat:@" AND (difficulty <= %d)", paramController.diff.selectedSegmentIndex + 1];
predicateString = [predicateString stringByAppendingString:diff];
NSString *timeString = [NSString stringWithFormat:@" AND (%d =< prepTime) AND (prepTime <= %d)", paramController.rangeSlider.leftValue, paramController.rangeSlider.rightValue];
predicateString = [predicateString stringByAppendingString:timeString];
if (paramController.categoryCode) {
NSString *categoryString = [NSString stringWithFormat:@" AND (inCategory = %@)", paramController.categoryCode];
predicateString = [predicateString stringByAppendingString:categoryString];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat: predicateString];
[resultController findRecipesWithPredicate:predicate];
}
Полный предикатString @"(code IN (\n 1,\n 3\n)) AND (difficulty <= 5) AND (0 =< prepTime) AND (prepTime <= 28800) AND (inCategory = 12)"
Теперь у меня есть ошибка в предикатной части (код IN% @), когда я готовлю NSPredicate с кодом:
NSPredicate *predicate = [NSPredicate predicateWithFormat: predicateString];
ERROR:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "(code IN (
1,
3
)) AND (difficulty <= 5) AND (0 =< prepTime) AND (prepTime <= 28800) AND (inCategory = 12)"'
Как правильно сделать предикат с помощью оператора IN. Спасибо за все советы.
Ответы
Ответ 1
используйте NSCompoundPredicate
для своих нескольких предикатов, вы можете ссылаться Ссылка на класс NSCompoundPredicate
что-то вроде этого:
NSPredicate * andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate1,predicate2,predicate3,nil]];
Ответ 2
Дополнение к ответу @Joshua, вы также можете использовать NSCompoundPredicate для своих операций OR, подобных этому.
Obj-C - OR
// OR Condition //
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"];
NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[predicate1, predicate2]];
Swift - OR
let predicate1:NSPredicate = NSPredicate(format: "X == 1")
let predicate2:NSPredicate = NSPredicate(format: "Y == 2")
let predicate:NSPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1,predicate2] )
Swift 3 - OR
let predicate1 = NSPredicate(format: "X == 1")
let predicate2 = NSPredicate(format: "Y == 2")
let predicateCompound = NSCompoundPredicate.init(type: .or, subpredicates: [predicate1,predicate2])
Ответ 3
Он будет работать для вас.
NSPredicate *bPredicate;
bPredicate = [NSPredicate predicateWithFormat:@"name contains[c] %@ OR product_price contains[c] %@ OR foodescription contains[c] %@",searchText,searchText,searchText];
NSArray *filteredArray = [getObjectsFromServiceArray filteredArrayUsingPredicate:bPredicate];