46

Looked high and low for this one but can't find my answer. I am looking to query core data for all records which are NOT equal to a specified string. For example, all records which are not equal to the current session ID. I have tried these to no avail:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"listingID != %@", [sitListingID objectAtIndex:i]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ NOT CONTAINS[cd] %@",@"listingID", [sitListingID objectAtIndex:i]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ NOT CONTAINS %@",@"listingID", [sitListingID objectAtIndex:i]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"listingID NOT like %@", [sitListingID objectAtIndex:i]];

Nothing works.HEEEEELP!!! ----------------------------------------------------- more code

NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ListingRecord" inManagedObjectContext:context];
    [request setEntity:entity];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sessionID <> %@", uniqueSessionListings];
    [request setPredicate:predicate];
    NSError *error = nil;
    NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
sangony
  • 11,636
  • 4
  • 39
  • 55

1 Answers1

123

Your first predicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"listingID != %@", sessionID];

should work to find all records where the attribute listingID is not equal to sessionID (provided that listingID and sessionID have the same type).

If both are strings and you want to find all records where listingID does not contain the string sessionID as a substring, then this predicate should work:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (listingID CONTAINS %@)", sessionID];

Use "CONTAINS[cd]" if the string comparison should be done case and diacritical insensitive.

NOTE: You can specify the attribute name as an argument, but then you must use %K instead of %@ as format:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (%K CONTAINS %@)", @"listingID", sessionID];
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • 1
    HECK YEAH! That did the trick. Quick side question, unless I am going blind I did not read your solution in the Apple Predicate Programming Guide. Did I miss it in the guide or is this covered somewhere else? (asking for future reference) – sangony Sep 21 '12 at 18:42
  • 3
    @sangony: When I started with Core Data programming I had also difficulties with predicates, the Predicate Programming Guide could be more detailed. It is sometimes tricky to combine all the possible comparisons, operations and predicates in the right order. You could say that everything is said in the "BNF Definition of Cocoa Predicates" :-) - I learned a lot from reading other people's questions and answers here at SO. – Martin R Sep 21 '12 at 20:44
  • 2
    This is helpful but is there a way to add a "does not contain" operator to an `NSPredicateEditorRowTemplate`? There is a `NSContainsPredicateOperatorType` but not a `NSDoesNotContainPredicateOperatorType` (unless I've missed it). – Jon Jan 11 '13 at 22:17
  • @Jon: I don't know. Normally I use `predicateWithFormat` and seldom build predicate programmatically. I assume that there is some way to *negate* an expression ... – Martin R Jan 11 '13 at 22:48
  • @MartinR I solved this by using a custom `NSPredicateEditorRowTemplate`. The custom class overrides the `templateViews` method and sets a custom popup to handle the "contains" and "does not contain" operators. Then, in the `setPredicate:` method, it **does not** set its (or super's) predicate. Instead, it parses the predicate format passed in and saves the operator & right-side expression to ivars. Then, in the `predicateWithSubpredicates:` method it creates a new predicate and, if it is "does not contain" operator, it returns the `NSCompoundPredicate notPredicateWithSubpredicate` predicate. – Jon Jan 12 '13 at 04:36
  • @MartinR are the brackets around "%k CONTAINS %@" required/needed? – pnizzle Jul 06 '15 at 01:08
  • @pnizzle: Probably not, but I did not test it. – Martin R Jul 06 '15 at 05:17
  • Super tip about %K that is easy to forget – yano Nov 03 '15 at 19:12
  • @MartinR how to perform same kind of task in swift 3.0 – Himanshu Moradiya Aug 25 '17 at 11:12
  • @HimanshuMoradiya: `let predicate = NSPredicate(format: "...", ...)` – the format string is the same as in Objective-C. – Martin R Aug 25 '17 at 11:22
  • thank you for replay but now I got answer if you don't mind then I just edit in your answer – Himanshu Moradiya Aug 25 '17 at 11:59