Search code examples
objective-ccocoa-touchiosnspredicatensmutablestring

What's the best way to generate this string? (NSMutableString...)


I have a dictionary whose keys are NSStrings and whose objects are NSArray. Here's an example:

key (NSString) : GroupA 
value (NSArray): John
                 Alex
                 Joe
                 Bob

There are many entries like this, this is just an example. What I need to do is generate a string like this (for example:

(GroupA contains[cd] ('John' OR 'Alex' OR 'Joe' OR 'Bob')) AND (GroupB contains[cd] ('Starcraft' OR 'WOW' OR 'Warcraft' OR 'Diablo')) AND ..... 

I am going to be feeding this string to an NSPredicate. What's the best way to generate this string? I can use for loops and if and all that, but is there a much more elegant way? Thanks.


Solution

  • That's not a valid predicate format string, so even if you end up generating it, you won't be able to convert it into an NSPredicate

    Here's what you want instead:

    NSDictionary *groupValuePairs = ....;
    
    NSMutableArray *subpredicates = [NSMutableArray array];
    for (NSString *group in groupValuePairs) {
      NSArray *values = [groupValuePairs objectForKey:group];
      NSPredicate *p = [NSPredicate predicateWithFormat:@"%K IN %@", group, values];
      [subpredicates addObject:p];
    }
    
    NSPredicate *final = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
    

    This doesn't have the case- and diacritic-insensitivity that your original was implying. If you really need that, then you're going to need to get a bit more complicated:

    NSDictionary *groupValuePairs = ....;
    
    NSMutableArray *subpredicates = [NSMutableArray array];
    for (NSString *group in groupValuePairs) {
      NSArray *values = [groupValuePairs objectForKey:group];
      NSMutableArray *groupSubpredicates = [NSMutableArray array];
      for (NSString *value in values) {
          NSPredicate *p = [NSPredicate predicateWithFormat:@"%K contains[cd] %@", group, value];
          [groupSubpredicates addObject:p];
      }
      NSPredicate *p = [NSCompoundPredicate orPredicateWithSubpredicates:groupSubpredicates];
      [subpredicates addObject:p];
    }
    
    NSPredicate *final = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];