Friday, July 1, 2016

Objective C NSPredicate Part 3/4

In the first part, We have seen some Basic comparisons and in the second part, We have seen String comparisons. In this part let's see some compound comparisons.

Let's take an array of users which may come as a JSON service response. I am hardcoding the stuff here.


   
 NSMutableArray *arrUsers = [[NSMutableArray allocinit];
    
    for(int i=0;i<=5;i++){
        
        NSMutableDictionary *dict = [[NSMutableDictionary allocinit];
        
        switch (i) {
                
            case 0:

                [dict setObject:@"John" forKey:@"name"];
                [dict setObject:@"Programmer" forKey:@"designation"];
                [dict setObject:[NSNumber numberWithInt:10000forKey:@"salary"];
                break;
                
            case 1:

                [dict setObject:@"Smith" forKey:@"name"];
                [dict setObject:@"Senior Manager" forKey:@"designation"];
                [dict setObject:[NSNumber numberWithInt:35000forKey:@"salary"];
                break;
                
            case 2:
                [dict setObject:@"Tim" forKey:@"name"];
                [dict setObject:@"Manager" forKey:@"designation"];
                [dict setObject:[NSNumber numberWithInt:30000forKey:@"salary"];
                break;
                
            case 3:

                [dict setObject:@"James" forKey:@"name"];
                [dict setObject:@"Senior Manager" forKey:@"designation"];
                [dict setObject:[NSNumber numberWithInt:32000forKey:@"salary"];
                break;
                
            case 4:

                [dict setObject:@"George" forKey:@"name"];
                [dict setObject:@"Manager" forKey:@"designation"];
                [dict setObject:[NSNumber numberWithInt:28000forKey:@"salary"];
                break;
                
            case 5:

                [dict setObject:@"Martin" forKey:@"name"];
                [dict setObject:@"Manager" forKey:@"designation"];
                [dict setObject:[NSNumber numberWithInt:26000forKey:@"salary"];
                break;
                
            default:
                break;
        }
        
        
        [arrUsers addObject:dict];
        
    }


Now we have a list of all users and we have their name, designation and salary. We may need to filter those users for display purpose based on their name/designation/salary. Let's see some example scenarios and the predicates which works for that filtration.

#1 All the users having salary greater than 30000 and designation is Manager and above


   
 NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                              @"(%K > %d) AND (%K contains[c] %@)",@"salary",    
            [[NSNumber numberWithInt:30000intValue],@"designation",@"manager"];

    
    NSArray *filteredArr = [arrUsers filteredArrayUsingPredicate:predicate];
    
    NSLog(@"Filtered Arr : %@",filteredArr);


  filteredArr : (
        {
        designation = "Senior Manager";
        name = Smith;
        salary = 35000;
    },
        {
        designation = "Senior Manager";
        name = James;
        salary = 32000;
    }
  )



In the predicate, %K is the placeholder for the key values (salary, designation...).

The same predicate can be split into 2 separate predicates and could be applied on the list as shown below.





   
 NSPredicate *onSalary = [NSPredicate predicateWithFormat:
               @"%K > %d",@"salary",[[NSNumber numberWithInt:30000intValue]];

    NSPredicate *onDesignation = [NSPredicate predicateWithFormat:
                                              @"%K contains[c] %@",@"designation",@"manager"];
    
    NSPredicate *predicate = [NSCompoundPredicate 
                              andPredicateWithSubpredicates:@[onSalary, onDesignation]];                                                                                  
    
    NSArray *filteredArr = [arrUsers filteredArrayUsingPredicate:predicate];
    
    NSLog(@"filteredArr : %@",filteredArr);

  filteredArr : (
        {
        designation = "Senior Manager";
        name = Smith;
        salary = 35000;
    },
        {
        designation = "Senior Manager";
        name = James;
        salary = 32000;
    }
  )



#2 All the users having Manager and above as designation and name containing either 'ti' or 'it'


   
 NSPredicate *predicate = [NSPredicate predicateWithFormat:
                               @"(%K contains[c] %@) AND ((name contains[c] %@) OR 
                 (name contains[c] %@))",@"designation",@"manager",@"ti",@"it"];
    
    NSArray *filteredArr = [arrUsers filteredArrayUsingPredicate:predicate];
    
    NSLog(@"filteredArr : %@",filteredArr);

  filteredArr : (
        {
        designation = "Senior Manager";
        name = Smith;
        salary = 35000;
    },
        {
        designation = Manager;
        name = Tim;
        salary = 30000;
    },
        {
        designation = Manager;
        name = Martin;
        salary = 26000;
    }
  )


Using AND, I have added a sub query here with an OR condition for name.


#3 Among some users, I need to check who and all are having salary > 30000



   
 NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                     @"(name in {%@, %@, %@}) AND (salary > %d)",
                                                      @"Tim",@"Martin",@"James",@"Smith",
                                          [[NSNumber numberWithInt:30000intValue]];
    
    NSArray *filteredArr = [arrUsers filteredArrayUsingPredicate:predicate];
    
    NSLog(@"filteredArr : %@",filteredArr);

  filteredArr : (
        {
        designation = "Senior Manager";
        name = Smith;
        salary = 35000;
    },
        {
        designation = "Senior Manager";
        name = James;
        salary = 32000;
    }
  )


I am checking among {Tim, Martin, James, Smith}, whose salary is greater than 30000. For that I am using IN operation, which filters users having the names in that list.

In the next part, let's discuss Relational operations.

Hope this post is useful. Feel free to comment in case of any queries.