NSArray map

I had an NSArray of objects (all the same). I needed a property out of all of those objects. So I created a Category on NSArray to add this functionality. It loops through each object and performs a selector creating a new array from the results. One important note is that since you can’t put Nil in an NSArray it does a check for Nil and doesn’t add that result. Therefore you do not get a perfect one to one map in all cases :(. The objects returned from the mapping (in my case) also needed to be serialized (a custom serializer I wrote). So I called mapByPerformingSelector again to much success. Then I realized that looping though the array twice was a waste so I created the mapWithBlock method. Simply supplying a block that asks for the needed property and then returning the serialized version of the returned object handled what I needed and only looped through the objects once. Success!

typedef id (^MapResult)(id obj);

@interface NSArray (NSArrayMap)

- (NSMutableArray*)mapByPerformingSelector:(SEL)sel;
- (NSMutableArray*)mapWithBlock:(MapResult)map;

@end
@implementation  NSArray (NSArrayMap)

- (NSMutableArray*)mapByPerformingSelector:(SEL)sel {
NSMutableArray * new = [NSMutableArray arrayWithCapacity:[self count]];

for (id obj in self) {
id t = [obj performSelector:sel];
if (t) {
[new addObject:t];
}
}

return new;
}

- (NSMutableArray*)mapWithBlock:(MapResult)map {
NSMutableArray * new = [NSMutableArray arrayWithCapacity:[self count]];

for (id obj in self) {
id t = map(obj);
if (t) {
[new addObject:t];
}
}

return new;
}

@end

As you can see these methods return NSMutableArrays… why? it was easier.

Example:

NSMutableArray* results = [sourceArray mapWithBlock:^id(id obj) {
PropertyType * r = ((ObjectType*)obj).property;
return [r serialize];
}];