Note, this is a start of this implementation, and I don’t consider it complete. In particular, I’d like it to take advantage of concurrency and Grand Central Dispatch in the future, and expand it to different kinds of sequences.
But anyway, I decided to give implementations of map, reduce, and filter for iOS development a try. Here we go.
First, let’s define some function block types:
typedef id (^MapBlock)(id);
typedef id (^ReduceBlock)(id, id);
typedef BOOL (^FilterBlock)(id);
This defines block types that (1) apply a function to an object, returning the result; (2) takes an accumulation as the first argument, the next object in the sequence as the second, and returns the next accumulation; and (3) is a simple predicate, which takes an object and returns a truth value based on that argument.
Now, let’s define a category for NSArray:
@interface NSArray (mapReduceFilter)
- (NSArray *) arrayByMappingWithBlock: (MapBlock) block;
- (id) valueByReducingWithBlock: (ReduceBlock) block;
- (NSArray *) arrayByFilteringWithBlock: (FilterBlock) block;
@end
And then, a straightforward implementation:
@implementation NSArray(mapReduceFilter)
- (NSArray *) arrayByMappingWithBlock:(MapBlock)block
{
NSMutableArray *ret = [NSMutableArray arrayWithCapacity: [self count]];
for (id value in self)
{
[ret addObject: block(value)];
}
return [NSArray arrayWithArray: ret];
}
- (id) valueByReducingWithBlock:(ReduceBlock)block
{
id ret = nil;
for (id value in self)
ret = block(ret, value);
return ret;
}
- (NSArray *) arrayByFilteringWithBlock: (FilterBlock) block
{
NSMutableArray *ret = [NSMutableArray arrayWithCapacity: [self count]];
for (id value in self)
if (block(value))
[ret addObject: value];
return [NSArray arrayWithArray: ret];
}
@end