When you filter a collection, you compare its objects to a logical statement to get a resultant collection that only contains objects for which the statement is true.
A predicate contains a statement that might be true, like “The employeeID is greater than 75.” There is a class called NSPredicate. NSMutableArray has a handy method for discarding all the objects that do not satisfy the predicate:
- (void)filterUsingPredicate:(NSPredicate *)predicate;
With NSArray, you cannot remove objects that do not match the predicate. Instead, NSArray has a method that creates a new array that contains all the objects that satisfy the predicate:
- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate;
Imagine that you are going to reclaim all the assets given to employees who currently hold assets worth more than $70 total. Add the code near the end of main.m:
... // Print out the CEO's information NSLog(@"CEO: %@", executives[@"CEO"]); executives = nil; NSPredicate *predicate = [NSPredicate predicateWithFormat: @"holder.valueOfAssets > 70"]; NSArray *toBeReclaimed = [allAssets filteredArrayUsingPredicate:predicate]; NSLog(@"toBeReclaimed: %@", toBeReclaimed); toBeReclaimed = nil; NSLog(@"Giving up ownership of arrays"); allAssets = nil; employees = nil; } return 0; }
Build and run the program. You should see a list of assets:
toBeReclaimed: ( "<Laptop 1: $17, assigned to <Employee 6: $119 in assets>>", "<Laptop 3: $51, assigned to <Employee 5: $136 in assets>>", "<Laptop 5: $85, assigned to <Employee 5: $136 in assets>>", "<Laptop 6: $102, assigned to <Employee 6: $119 in assets>>", "<Laptop 8: $136, assigned to <Employee 9: $136 in assets>>", "<Laptop 9: $153, assigned to <Employee 1: $153 in assets>>" )
The format string used to create the predicate can be very complex. If you do a lot of filtering of collections, be sure to read Apple’s Predicate Programming Guide.
Filtering can be done with sets as well as arrays. NSSet has the method:
- (NSSet *)filteredSetUsingPredicate:(NSPredicate *)predicate;
and NSMutableSet has the method:
- (void)filterUsingPredicate:(NSPredicate *)predicate;