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]; }];