【问题标题】:Multiple NSPredicate多个 NSPredicate
【发布时间】:2017-03-07 19:04:39
【问题描述】:

我正在尝试在我的 CoreData 实体 Recipes 中准备多个搜索。我想通过一些参数来准备 fetch。

食谱属性:

@property (nonatomic, retain) NSNumber * difficulty;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * code; //like identifier
@property (nonatomic, retain) NSNumber * prepTime;

Ingredients 是一个单独的实体,包含成分列表。

Join 实体包含 ingredientCoderecipeCodecount

getArrayOfJoinDataWithIngredients 获取 join 实体并返回包含一些输入成分的食谱的 codes 的 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];
}

完整的谓词字符串是@"(code IN (\n 1,\n 3\n)) AND (difficulty &lt;= 5) AND (0 =&lt; prepTime) AND (prepTime &lt;= 28800) AND (inCategory = 12)"

现在,当我使用代码准备 NSPredicate 时,谓词部分 (code IN %@) 出现错误:

NSPredicate *predicate = [NSPredicate predicateWithFormat: predicateString];

错误:

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 运算符制作谓词。感谢所有建议。

【问题讨论】:

    标签: ios nspredicate


    【解决方案1】:

    多个谓词使用NSCompoundPredicate,可以参考NSCompoundPredicate Class Reference

    类似这样的:

    NSPredicate * andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate1,predicate2,predicate3,nil]];
    

    【讨论】:

      【解决方案2】:

      除了@Joshua 的回答,您还可以像这样使用 NSCompoundPredicate 进行 OR 操作。

      Obj-C - 或

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

      斯威夫特 - 或

      let predicate1:NSPredicate = NSPredicate(format: "X == 1")
      let predicate2:NSPredicate = NSPredicate(format: "Y == 2")
      let predicate:NSPredicate  = NSCompoundPredicate(orPredicateWithSubpredicates: [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])
      

      【讨论】:

        【解决方案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];
        

        【讨论】:

          猜你喜欢
          • 2012-04-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多