8

I'm not even sure of this is possible, but if it is, it could surely help.

I have an NSArray of NSDictionaries.

Each dictionary has certain keys (obviously).

Dict{ 
 Title: WBCCount
 Cat: Lab
}
Dict{
 Title: HbM
 Cat: Lab
 Sex: Male
}
Dict{
 Title: HbF
 Cat: Lab
 Sex: Female
}
Dict{
  Title: PC_Count
  Cat: CBC
  Sex: Female
}

I wanted to filter array with dictionaries that have Cat = 'Lab' and IF Sex as a key is present in the dictionary object, get the one with Male.

In short, I cannot put together a

predicateWithFormate:%@" Cat = Lab AND ( if Sex key is present, Sex = Male";

This would get me an array of WBC, HbM.

I don't know if this is possible, a condition within a predicate, but it would be a life saver if it was as this is how the objects are sent via web API.

Any other way of achiving the goal if not this would also be great.

While we are in the subject of Core Data, this should be simple: I want to have an attribute of the entity to be able to store either NSDate or NSNumber or NSString. Is there an easy way out?

Monolo
  • 18,205
  • 17
  • 69
  • 103
jasonIM
  • 193
  • 2
  • 13

2 Answers2

7

The trick here is that in an NSDictionary, a non-present key just returns nil:

NSArray *dictionaries = @[
    @{ @"Title": @"T1",  @"Cat":   @"Lab",   @"Sex":   @"Male"   },
    @{ @"Title": @"T2",  @"Cat":   @"C2"                         },
    @{ @"Title": @"T3",  @"Cat":   @"Lab",   @"Sex":   @"Female" },
    @{ @"Title": @"T4",  @"Cat":   @"Lab"                        }
];                    

NSPredicate *pred = [NSPredicate predicateWithFormat:@"(Sex == nil OR Sex = 'Male') AND Cat = 'Lab'" ];

NSArray *result = [dictionaries filteredArrayUsingPredicate:pred];
Monolo
  • 18,205
  • 17
  • 69
  • 103
  • Hey thanks for replying :) , but you forgot one more NSDictionary to include, if the array has `dict{Title:T4, Cat:Lab}` i want this to also be returned in the array, since theres no mention of Sex, its assumed to be applicable to both sexes. – jasonIM Jun 05 '12 at 21:49
  • Some kinda subquery might be required? or maybe its just not possible via NSPredicate – jasonIM Jun 05 '12 at 21:51
  • Again, if I understand the question correctly, you want to get records (=dictionaries) which have no Sex attribute, or have a Sex attribute of Male (or both, of course). I have modified the code to do that. Hope this is what you are after. – Monolo Jun 05 '12 at 22:13
  • NICE, thanks man! i cant believe that checking a key exists was as simple as key == nil! – jasonIM Jun 05 '12 at 22:55
  • Given that there are only three values (Male, Female, or nil) in this case, you should be able to use `Cat = 'Lab' AND Sex != 'Female'`. – Ken Thomases Jun 06 '12 at 08:46
5

Another syntax (but available for collections only) for checking key existance is:

NSPredicate *p = [NSPredicate predicateWithFormat:@"Sex in SELF"]

I use it often with Parse.com

wzs
  • 1,057
  • 9
  • 12