77

I have an NSArray and need to filter out any strings that are null or rather, have ' ' (empty string). How do I do that? I have tried doing:

NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"(name!=nil)"]; 

but that doesn't seem to work. Or maybe it does but there are different kinds of null...

IPS Brar
  • 346
  • 1
  • 14
Doz
  • 7,009
  • 12
  • 61
  • 69

4 Answers4

153

If you don't use Core Data, you could do:

NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"name.length > 0"];

If the string is empty, this will fail (because 0 == 0). Similarly, if name is nil, it will also fail, because [nil length] == 0.

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • So then what is the solution mate? This one actually seems to work for me where as the first answer doesn't. If string is empty, then wont length = 0? it isn't null – Doz Sep 10 '11 at 04:56
  • @Doron the solution is to use the predicate I suggested. – Dave DeLong Sep 11 '11 at 03:53
  • Sorry mate but i still get (null) in certain fields. So not sure what you meant by your comment after the code. == 0 so you are saying you are getting a value of 0, so all i need to test is > 0. to be 1. Because i am still getting (null) – Doz Sep 11 '11 at 11:24
  • 2011-09-11 21:24:14.282 iKosher[89194:13703] Brand**COLES 2011-09-11 21:24:14.282 iKosher[89194:13703] Brand**WAITROSE 2011-09-11 21:24:14.283 iKosher[89194:13703] Brand**(null) 2011-09-11 21:24:14.283 iKosher[89194:13703] Brand**(null) 2011-09-11 21:24:14.283 iKosher[89194:13703] Brand**VILLAGE GREEN – Doz Sep 11 '11 at 11:24
  • 87
    !!! **Beware with CoreData** length is not supported, and worse will fail silently returning strange results. CoreData translates the predicate `name.length > 1` to sqlite in `name > 1`... While it should be `length(name) > 1` – Vincent Guerci May 07 '12 at 14:06
  • @VincentG interesting. sounds like a bug. have you filed one? https://bugreport.apple.com – Dave DeLong May 07 '12 at 15:44
  • @Dave DeLong, just did, searched a while in `CoreData`/`NSPredicate` documentation, no mention at all of `length`. Makes sense that it works on object arrays thanks to `keypath` evaluation. But on sqlite, I presume that is not so obvious... Maybe a missing feature, but anyway, that should raise an error in that case. – Vincent Guerci May 07 '12 at 16:09
  • So does this answer not work then? I'm having a similar problem – trapper Oct 23 '12 at 14:17
  • I just used the suggested technique (i.e. name.length > 0) in a core-data NSPredicate and it worked as expected so if it was broken then it is fixed now (iOS 6.1 on Simulator). – Christopher King Feb 10 '13 at 19:12
  • I noticed that when `name`.length > 0 but `name` the first character is a whitespace -> it will not return it – Tal Bereznitskey Feb 18 '13 at 09:59
  • 34
    Got tricked once again today by this one with CoreData... damn it. Kinda funny that I found my own previous comment looking for this :) – Vincent Guerci Mar 14 '13 at 12:38
  • @VincentG how about [using a regular expression](http://stackoverflow.com/a/14148659/375300) for a Core Data predicate (as long as it is performant enough)? – albertamg Aug 21 '13 at 13:24
  • what about objects that aren't strings? – Ben Collins Jan 27 '14 at 17:12
  • 8
    @VincentG - then what is the solution for CoreData? – RyanJM Mar 05 '14 at 21:44
  • 2
    This is very dangerous. @VincentG is right. I have a string with a leading '/' character which did not work with `.length`. I had to use the `name!=nil AND name!=''` like @josema.vitaminew posted – Stefan Arn Nov 20 '15 at 13:09
89

I think this should work:

NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"name!=nil AND name!=''"]; 
José Manuel Sánchez
  • 5,215
  • 2
  • 31
  • 24
14
 NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"name!=NULL"];
chroww
  • 183
  • 1
  • 4
7

This predicate worked for me:

[NSPredicate predicateWithFormat:@"(%K== nil) OR %K.length == 0", @"imageUrl", @"imageUrl"]
Josip B.
  • 2,434
  • 1
  • 25
  • 30