Created
March 2, 2012 15:26
-
-
Save zwaldowski/1959168 to your computer and use it in GitHub Desktop.
NSOrderedSet for BlocksKit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Pod::Spec.new do |s| | |
s.name = 'BlocksKit+NSOrderedSet' | |
s.version = '1.0.0' | |
s.license = 'MIT' | |
s.summary = 'The NSOrderedSet block utilities you always wish you had.' | |
s.homepage = 'https://github.com/zwaldowski/BlocksKit' | |
s.author = { 'Zachary Waldowski' => '[email protected]' } | |
s.source = { :git => 'git://gist.github.com/1959168.git', :tag => 'origin/master' } | |
s.source_files = '*.{h,m}' | |
s.dependency 'BlocksKit' | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSMutableOrderedSet+BlocksKit.h | |
// %PROJECT | |
// | |
#import "BKGlobals.h" | |
/** Block extensions for NSMutableOrderedSet. | |
These utilities expound upon the BlocksKit additions | |
to the immutable superclass by allowing certain utilities | |
to work on an instance of the mutable class, saving memory | |
by not creating an immutable copy of the results. | |
Includes code by the following: | |
- Zach Waldowski. <https://github.com/zwaldowski>. 2012. MIT. | |
@warning NSMutableOrderedSet is only available on iOS 5.0, OS X 10.7, or later. | |
@see NSOrderedSet(BlocksKit) | |
*/ | |
@interface NSMutableOrderedSet (BlocksKit) | |
/** Filters a mutable ordered set to the objects matching the block. | |
@param block A single-argument, BOOL-returning code block. | |
@see reject: | |
*/ | |
- (void)performSelect:(BKValidationBlock)block; | |
/** Filters a mutable ordered set to all objects but the ones matching the block, | |
the logical inverse to select:. | |
@param block A single-argument, BOOL-returning code block. | |
@see select: | |
*/ | |
- (void)performReject:(BKValidationBlock)block; | |
/** Transform the objects in the set to the results of the block. | |
This is sometimes referred to as a transform, mutating one of each object: | |
[controllers map:^id(id obj) { | |
return [obj view]; | |
}]; | |
@param block A single-argument, object-returning code block. | |
*/ | |
- (void)performMap:(BKTransformBlock)block; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSMutableOrderedSet+BlocksKit.m | |
// BlocksKit | |
// | |
#import "NSMutableOrderedSet+BlocksKit.h" | |
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_5_0 | |
@implementation NSMutableOrderedSet (BlocksKit) | |
- (void)performSelect:(BKValidationBlock)block { | |
NSParameterAssert(block != nil); | |
NSIndexSet *list = [self indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { | |
return !block(obj); | |
}]; | |
if (!list.count) | |
return; | |
[self removeObjectsAtIndexes:list]; | |
} | |
- (void)performReject:(BKValidationBlock)block { | |
[self performSelect:^BOOL(id obj) { | |
return !block(obj); | |
}]; | |
} | |
- (void)performMap:(BKTransformBlock)block { | |
NSParameterAssert(block != nil); | |
NSMutableArray *new = [NSMutableArray arrayWithCapacity:self.count]; | |
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
id value = block(obj); | |
if (!value) | |
value = [NSNull null]; | |
[new addObject:value]; | |
}]; | |
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.count)]; | |
[self replaceObjectsAtIndexes:indexes withObjects:new]; | |
} | |
@end | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSOrderedSet+BlocksKit.h | |
// %PROJECT | |
// | |
/** Block extensions for NSOrderedSet. | |
Both inspired by and resembling Smalltalk syntax, these utilities | |
allows for iteration of an ordered set in a concise way that | |
saves quite a bit of boilerplate code for filtering or finding | |
objects or an object. | |
Includes code by the following: | |
- Zach Waldowski. <https://github.com/zwaldowski>. 2012. MIT. | |
@warning NSOrderedSet is only available on iOS 5.0, OS X 10.7, or later. | |
@see NSArray(BlocksKit) | |
@see NSSet(BlocksKit) | |
*/ | |
@interface NSOrderedSet (BlocksKit) | |
/** Loops through an ordered set and executes the given block with each object. | |
@param block A single-argument, void-returning code block. | |
*/ | |
- (void)each:(BKSenderBlock)block; | |
/** Enumerates through an ordered set concurrently and executes | |
the given block once for each object. | |
Enumeration will occur on appropriate background queues. This | |
will have a noticeable speed increase, especially on dual-core | |
devices, but you *must* be aware of the thread safety of the | |
objects you message from within the block. | |
@param block A single-argument, void-returning code block. | |
*/ | |
- (void)apply:(BKSenderBlock)block; | |
/** Loops through an ordered set to find the object matching the block. | |
match: is functionally identical to select:, but will stop and return | |
on the first match. | |
@param block A single-argument, BOOL-returning code block. | |
@return Returns the object if found, `nil` otherwise. | |
@see select: | |
*/ | |
- (id)match:(BKValidationBlock)block; | |
/** Loops through an ordered set to find the objects matching the block. | |
@param block A single-argument, BOOL-returning code block. | |
@return Returns an ordered set of the objects found, `nil` otherwise. | |
@see match: | |
*/ | |
- (NSOrderedSet *)select:(BKValidationBlock)block; | |
/** Loops through an ordered set to find the objects not matching the block. | |
This selector performs *literally* the exact same function as select, but in reverse. | |
This is useful, as one may expect, for removing objects from an ordered set: | |
NSOrderedSet *new = [bookmarks reject:^BOOL(id obj) { | |
return ([obj isLoading]); | |
}]; | |
@param block A single-argument, BOOL-returning code block. | |
@return Returns an ordered set of all objects not found, `nil` if all are excluded. | |
*/ | |
- (NSOrderedSet *)reject:(BKValidationBlock)block; | |
/** Call the block once for each object and create an ordered set of the return values. | |
This is sometimes referred to as a transform, mutating one of each object: | |
NSOrderedSet *new = [mimeTypes map:^id(id obj) { | |
return [@"x-company-" stringByAppendingString:obj]); | |
}]; | |
@param block A single-argument, object-returning code block. | |
@return Returns an ordered set of the objects returned by the block. | |
*/ | |
- (NSOrderedSet *)map:(BKTransformBlock)block; | |
/** Arbitrarily accumulate objects using a block. | |
The concept of this selector is difficult to illustrate in words. The sum can | |
be any NSObject, including (but not limited to) an NSString, NSNumber, or NSValue. | |
You can also do something like summing the count of an item: | |
NSNumber *sum = [bodyList reduce:nil withBlock:^id(id sum, id obj) { | |
return [NSNumber numberWithInteger: [sum integerValue] + obj.numberOfAppendages]; | |
}]; | |
NSUInteger numberOfBodyParts = [sum integerValue]; | |
@param initial The value of the reduction at its start. | |
@param block A block that takes the current sum and the next object to return the new sum. | |
@return An accumulated value. | |
*/ | |
- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block; | |
/** Loops through an ordered set to find whether any object matches the block. | |
This method is similar to the Scala list `exists`. It is functionally | |
identical to match: but returns a `BOOL` instead. It is not recommended | |
to use any: as a check condition before executing match:, since it would | |
require two loops through the ordered set. | |
@param block A single-argument, BOOL-returning code block. | |
@return YES for the first time the block returns YES for an object, NO otherwise. | |
*/ | |
- (BOOL)any:(BKValidationBlock)block; | |
/** Loops through an ordered set to find whether no objects match the block. | |
This selector performs *literally* the exact same function as all: but in reverse. | |
@param block A single-argument, BOOL-returning code block. | |
@return YES if the block returns NO for all objects in the ordered set, NO otherwise. | |
*/ | |
- (BOOL)none:(BKValidationBlock)block; | |
/** Loops through an ordered set to find whether all objects match the block. | |
@param block A single-argument, BOOL-returning code block. | |
@return YES if the block returns YES for all objects in the ordered set, NO otherwise. | |
*/ | |
- (BOOL)all:(BKValidationBlock)block; | |
/** Tests whether every element of this ordered set relates to the corresponding | |
element of another ordered set according to the block. | |
@param block A two-argument, BOOL-returning code block. | |
@return YES if every element relates to the corresponding element in the other collection, NO otherwise. | |
*/ | |
- (BOOL)corresponds:(NSOrderedSet *)list withBlock:(BKKeyValueValidationBlock)block; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSOrderedSet+BlocksKit.m | |
// BlocksKit | |
// | |
#import "NSOrderedSet+BlocksKit.h" | |
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_5_0 | |
@implementation NSOrderedSet (BlocksKit) | |
- (void)each:(BKSenderBlock)block { | |
NSParameterAssert(block != nil); | |
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
block(obj); | |
}]; | |
} | |
- (void)apply:(BKSenderBlock)block { | |
NSParameterAssert(block != nil); | |
[self enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
block(obj); | |
}]; | |
} | |
- (id)match:(BKValidationBlock)block { | |
NSParameterAssert(block != nil); | |
NSUInteger index = [self indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { | |
return block(obj); | |
}]; | |
if (index == NSNotFound) | |
return nil; | |
return [self objectAtIndex:index]; | |
} | |
- (NSOrderedSet *)select:(BKValidationBlock)block { | |
NSParameterAssert(block != nil); | |
NSArray *objects = [self objectsAtIndexes:[self indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { | |
return block(obj); | |
}]]; | |
if (!objects.count) | |
return nil; | |
return [[self class] orderedSetWithArray:objects]; | |
} | |
- (NSOrderedSet *)reject:(BKValidationBlock)block { | |
return [self select:^BOOL(id obj) { | |
return !block(obj); | |
}]; | |
} | |
- (NSOrderedSet *)map:(BKTransformBlock)block { | |
NSParameterAssert(block != nil); | |
NSMutableOrderedSet *result = [NSMutableOrderedSet orderedSetWithCapacity:self.count]; | |
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
id value = block(obj); | |
if (!value) | |
value = [NSNull null]; | |
[result addObject:value]; | |
}]; | |
return result; | |
} | |
- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block { | |
NSParameterAssert(block != nil); | |
__block id result = [initial retain]; | |
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
id new = block(result, obj); | |
[result release]; | |
result = [new retain]; | |
}]; | |
return [result autorelease]; | |
} | |
- (BOOL)any:(BKValidationBlock)block { | |
return [self match: block] != nil; | |
} | |
- (BOOL)none:(BKValidationBlock)block { | |
return [self match: block] == nil; | |
} | |
- (BOOL)all:(BKValidationBlock)block { | |
NSParameterAssert(block != nil); | |
__block BOOL result = YES; | |
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
if (!block(obj)) { | |
result = NO; | |
*stop = YES; | |
} | |
}]; | |
return result; | |
} | |
- (BOOL)corresponds:(NSOrderedSet *)list withBlock:(BKKeyValueValidationBlock)block { | |
NSParameterAssert(block != nil); | |
__block BOOL result = NO; | |
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
if (idx < [list count]) { | |
id obj2 = [list objectAtIndex: idx]; | |
result = block(obj, obj2); | |
} else { | |
result = NO; | |
} | |
*stop = !result; | |
}]; | |
return result; | |
} | |
@end | |
BK_MAKE_CATEGORY_LOADABLE(NSOrderedSet_BlocksKit) | |
#endif |
Sorry wrong paste, meant to say that you are missing one #import "BKGlobals.h"
up there.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@zwaldowski You forgot an
git://gist.github.com/3889128.git
in the nsorderedset header file.