Skip to content

Instantly share code, notes, and snippets.

@spetschu
Last active December 24, 2015 01:09
Show Gist options
  • Save spetschu/bba2a4762d27324ac103 to your computer and use it in GitHub Desktop.
Save spetschu/bba2a4762d27324ac103 to your computer and use it in GitHub Desktop.
A few handy ruby/smalltalk-like list comprehensions.
typedef BOOL (^BooleanBlock)(id obj); // Returns true or false given an object
typedef id (^ValueBlock)(id obj); // Returns an object given an object (generally of the same type, may or may not be modified)
typedef id (^AccumulatorBlock)(id acc, id obj); // Returns the accumulator object, likely mutated.
// A few ruby-like list comprehensions.
@implementation NSArray (ListComprehensions)
// Returns the first object for which the block returns true. AKA array.match()
-(id) find:(BooleanBlock)block {
NSUInteger index = [self indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return block(obj);
}];
return ((index == NSNotFound) ? nil : self[index]);
}
// Returns a new array with only selected elements.
-(NSArray *) select:(BooleanBlock)block {
NSMutableArray *selected = [NSMutableArray array];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (block(obj)) [selected addObject:obj];
}];
return (NSArray *)selected;
}
// Iterates over array and returns a new array the same size as the current one. AKA map()
-(NSArray *) map:(ValueBlock)block {
NSMutableArray *collector = [NSMutableArray arrayWithCapacity:[self count]];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[collector addObject:block(obj)];
}];
return [collector copy];
}
-(id) reduceFromInitial:(id)value block:(AccumulatorBlock)block {
__block id acc = value;
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
acc = block(acc, obj);
}];
return acc;
}
@end
@spetschu
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment