0

I have an NSMutableArray of dictionaries. I am using NSPredicate to filter through the array to find if a dictionary with a particular key exists or not.

I have referred to various examples, one of the closest is here: Using NSPredicate to filter an NSArray based on NSDictionary keys. However, I don't wish to have a value to the key. My problem is that I want to find the key first. I tried different syntaxes, but it did not help.

What I have done so far:

    NSString *key = @"open_house_updated_endhour";
    NSPredicate *predicateString = [NSPredicate predicateWithFormat:@"%K", key];
    //NSPredicate *predicateString = [NSPredicate predicateWithFormat:@"%K contains [cd]", key]; Doesn't work.
    //NSPredicate *predicateString = [NSPredicate predicateWithFormat:@"%K == %@", key]; Won't work because it expects a value here.
    NSLog(@"predicate %@",predicateString);
    NSArray *filtered = [updatedDateAndTime filteredArrayUsingPredicate:predicate]; // updatedDateAndTime is the NSMutableArray
Community
  • 1
  • 1
Ron
  • 389
  • 1
  • 4
  • 16
  • so you just want to know if "a certain key" is present in the dictionaries contained in an array or not? – Adeel Miraj Oct 11 '16 at 19:17
  • @AdeelMiraj Yes, exactly! That's what I want. – Ron Oct 11 '16 at 19:19
  • In my opinion enumerating the array would be relatively easier and straight forward way to do this. Is there any particular reason for doing doing this through predicates? – Adeel Miraj Oct 11 '16 at 19:28
  • @AdeelMiraj... The reason why I am doing this is because I have redundant logic for various cells in the table view. Hence, I don't want to increase my code logic unnecessary. Also, as I am new to iOS, I wanted to use the available NSPredicate system to achieve this goal. – Ron Oct 11 '16 at 20:06

2 Answers2

3

A dictionary delivers nil as value for absent key. So simply compare the key against nil.

NSPredicate *predicateString = [NSPredicate predicateWithFormat:@"%K==NULL", key]; // Dictionaries not having the key
NSPredicate *predicateString = [NSPredicate predicateWithFormat:@"%K!=NULL", key]; // Dictionaries having the key
Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
  • Thanks a lot for your quick help. It helped. I get an array with the required dictionary object, if it exists. What if I want to use @"%K == NULL" || @"%K != NULL" ? If I do this, I get an error. Basically, I would like to update the dictionary if the key is found. It does not matter, if it is empty or not. No doubt, I like this simple solution. – Ron Oct 11 '16 at 19:59
  • I do not understand, why you want to use `@"%K == NULL" || @"%K != NULL"`. First of all there is an extra `"` after the first `NULL`, what is an error. Can you tell me the error you get? However, the expression would always be true. It makes no sense. – Amin Negm-Awad Oct 12 '16 at 01:40
0

Try it:

 NSArray *Myarray = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:@"my hello string" forKey:@"name"]];   
NSArray *filteredarray = [Myarray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(name == %@)", @"my hello string"]];
NSLog("%@",filteredarray);

Another example :

NSString *mycategory = @"iamsomeone";
NSArray *myitems = @[@{ @"types" : @[@"novel", @"iamsomeone", @"dog"] },
                   @{ @"types" : @[@"cow", @"iamsomeone-iam", @"dog"] },
                   @{ @"types" : @[@"cow", @"bow", @"cat"] }];
NSPredicate *mypredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    NSArray *categories = [evaluatedObject objectForKey:@"types"];
    return [categories containsObject:mycategory];
}];

NSArray *outpuArray = [myitems filteredArrayUsingPredicate:mypredicate];
NSLog(@"hello output:%@",outpuArray);
Jamshed Alam
  • 12,424
  • 5
  • 26
  • 49
  • Thanks for the quick response. However, the first example expects me to have a value for the key. In my case, it may or may not be there. Hence, I want to check for the key first. – Ron Oct 11 '16 at 19:34