filtering NSArray into a new NSArray in Objective-C
Based on an answer by Clay Bridges, here is an example of filtering using blocks (change yourArray
to your array variable name and testFunc
to the name of your testing function):
yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [self testFunc:obj];
}]];
NSArray
and NSMutableArray
provide methods to filter array contents. NSArray
provides filteredArrayUsingPredicate: which returns a new array containing objects in the receiver that match the specified predicate. NSMutableArray
adds filterUsingPredicate: which evaluates the receiver’s content against the specified predicate and leaves only objects that match. These methods are illustrated in the following example.
NSMutableArray *array =
[NSMutableArray arrayWithObjects:@"Bill", @"Ben", @"Chris", @"Melissa", nil];
NSPredicate *bPredicate =
[NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
NSArray *beginWithB =
[array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { @"Bill", @"Ben" }.
NSPredicate *sPredicate =
[NSPredicate predicateWithFormat:@"SELF contains[c] 's'"];
[array filteredArrayUsingPredicate:sPredicate];
// array now contains { @"Chris", @"Melissa" }
There are loads of ways to do this, but by far the neatest is surely using [NSPredicate predicateWithBlock:]
:
NSArray *filteredArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
return [object shouldIKeepYou]; // Return YES for each object you want in filteredArray.
}]];
I think that's about as concise as it gets.
Swift:
For those working with NSArray
s in Swift, you may prefer this even more concise version:
let filteredArray = array.filter { $0.shouldIKeepYou() }
filter
is just a method on Array
(NSArray
is implicitly bridged to Swift’s Array
). It takes one argument: a closure that takes one object in the array and returns a Bool
. In your closure, just return true
for any objects you want in the filtered array.