Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSPredicate: how to do NOT EndsWith?

I have a list of images in the app bundle and need to display appropriate ones in app, the image has the format:

###_photo_#.jpg

###: toy id, from 1000 to 2000
#: photo id, from 1

so for example

1000_photo_1.jpg
1000_photo_2.jpg

I used to get the list of files in the bundle and use a predicate to filter out other files:

@"self ENDSWITH '.jpg' AND self BEGINSWITH '%d_photo_'", toyId

but now there are retina images which end with @2x.jpg, so this method need to be fixed, I am thinking about adding:

NOT ENDSWITH '@2x.jpg'

but is this correct? should I say:

NOT (ENDSWITH '@2x.jpg')

or:

(NOT ENDSWITH '@2x.jpg')

instead?

like image 590
hzxu Avatar asked Aug 02 '12 01:08

hzxu


3 Answers

You can use a predicate string like this:

@"(self ENDSWITH '.jpg') AND NOT (self ENDSWITH '@2x.jpg') AND (self BEGINSWITH '%d_photo_')"
like image 60
rob mayoff Avatar answered Nov 11 '22 04:11

rob mayoff


You can encapsulate a predicate in another predicate:

NSPredicate *positivePredicate = [NSPredicate ...];
NSPredicate *negativePredicate = [NSCompoundPredicate notPredicateWithSubpredicate: positivePredicate];

This allows you to preserve the existing legible format string. Note that with NSCompoundPredicate, you can also build AND and OR predicates. From these three (AND, OR, NOT), you can even derive things like XNOR and NAND predicates (though how to do so is an exercise left to the reader...)

like image 24
Jonathan Grynspan Avatar answered Nov 11 '22 06:11

Jonathan Grynspan


I think a better option in iOS 4.0+ is to use NSPredicate predicateWithBlock: to define your conditions. That way you can use standard NSString functions like hasSuffix: to check for your endsWith negative case.

Checkout a good tutorial here: http://www.wannabegeek.com/?p=149

Here's a basic way you could use it.

NSInteger toyId = 10;
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
  return [evaluatedObject hasSuffix:@".jpg"] &&
  ![evaluatedObject hasSuffix:@"@2x.jpg"] &&
  [evaluatedObject hasPrefix:[NSString stringWithFormat:@"%@_photo_", [NSNumber numberWithInt:toyId]]];
}];

You can then grab your array of files

[arrayOfFiles filterArrayUsingPredicate:predicate];
like image 1
Jessedc Avatar answered Nov 11 '22 05:11

Jessedc