Skip to content
This repository has been archived by the owner on Dec 12, 2018. It is now read-only.

Added NSArray -sortWithBlock, -uniq, -indexOf and -partition #51

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions Classes/NSArray+ObjectiveSugar.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,49 @@
*/
- (NSArray *)sortBy:(NSString*)key;

/**
Sorts the array by mapping the values through the given block.

@return The sorted array
*/
- (NSArray *)sortWithBlock:(id (^)(id object))block;

/**
Alias for reverseObjectEnumerator.allObjects

Returns a reversed array
*/
- (NSArray *)reverse;

/**
Find the index of the first object for which block returns YES.

@return An index or NSNotFound if not found
*/
- (NSUInteger)indexOf:(BOOL (^)(id object))block;

/**
Returns two arrays, the first containing elements for
which block returns true, the second containing the rest.

@return An array containing the two arrays
*/
- (NSArray *)partition:(BOOL (^)(id object))block;

/**
Returns an array with only the unique objects from self.

@return An array containing the unique objects
*/
- (NSArray *)uniq;

/**
Compares self to another array using standard NSComparisonResult results

@return An NSComparisonResult
*/
- (NSComparisonResult)compare:(NSArray *)array;

/**
Return all the objects that are in both self and `array`.
Alias for Ruby's & operator
Expand Down
46 changes: 46 additions & 0 deletions Classes/NSArray+ObjectiveSugar.m
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,56 @@ - (NSArray *)sortBy:(NSString*)key; {
return [self sortedArrayUsingDescriptors:@[descriptor]];
}

- (NSArray *)sortWithBlock:(id (^)(id object))block {
NSArray *tuples = [self map:^(id object) { return @[block(object), object]; }];
return [tuples.sort map:^id(id object) { return object[1]; }];
}

- (NSArray *)reverse {
return self.reverseObjectEnumerator.allObjects;
}

- (NSUInteger)indexOf:(BOOL (^)(id object))block {
__block NSUInteger result = NSNotFound;
[self enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
if (block(object)) {
result = index;
*stop = YES;
}
}];
return result;
}

- (NSArray *)partition:(BOOL (^)(id object))block {
NSMutableArray *yes = [NSMutableArray array];
NSMutableArray *no = [NSMutableArray array];
for (id object in self) {
[(block(object) ? yes : no) addObject:object];
}
return @[ yes, no ];
}

- (NSArray *)uniq {
return [[NSSet setWithArray:self] allObjects];
}

// note: this is required for sortWithBlock
- (NSComparisonResult)compare:(NSArray *)array {
for (int index = 0; index < MAX(self.count, array.count); ++index) {
if (self.count <= index) {
return NSOrderedAscending;
}
if (array.count <= index) {
return NSOrderedDescending;
}
NSComparisonResult result = [self[index] compare:array[index]];
if (result != NSOrderedSame) {
return result;
}
}
return NSOrderedSame;
}

#pragma mark - Set operations

- (NSArray *)intersectionWithArray:(NSArray *)array {
Expand Down
60 changes: 59 additions & 1 deletion Example/ObjectiveSugarTests/NSArrayCategoriesTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,27 @@
});
});

context(@"comparing two arrays", ^{
NSArray *empty = @[ ];
NSArray *a = @[ @2, @3 ];
NSArray *b = @[ @2, @4 ];
NSArray *c = @[ @2, @3, @4 ];

// empty arrays
it(@"empty array == empty array", ^{ [[@([empty compare:empty]) should] equal:@(NSOrderedSame)]; });
it(@"empty array < some array", ^{ [[@([empty compare:a]) should] equal:@(NSOrderedAscending)]; });
it(@"some array > empty array", ^{ [[@([a compare:empty]) should] equal:@(NSOrderedDescending)]; });

// simple case
it(@"2,3 == 2,3", ^{ [[@([a compare:a]) should] equal:@(NSOrderedSame)]; });
it(@"2,3 < 2,4", ^{ [[@([a compare:b]) should] equal:@(NSOrderedAscending)]; });
it(@"2,4 > 2,3", ^{ [[@([b compare:a]) should] equal:@(NSOrderedDescending)]; });

// length mismatches
it(@"2,3 < 2,3,4", ^{ [[@([a compare:c]) should] equal:@(NSOrderedAscending)]; });
it(@"2,3,4 > 2,3", ^{ [[@([c compare:a]) should] equal:@(NSOrderedDescending)]; });
});

context(@"sorting", ^{

it(@"-sort aliases -sortUsingComparator:", ^{
Expand All @@ -195,9 +216,46 @@
NSDictionary *dict_4 = @{@"name": @"3"};
[[[@[ dict_4, dict_1, dict_3, dict_2 ] sortBy:@"name"] should] equal:@[ dict_1, dict_2, dict_3, dict_4 ]];
});


it(@"-sortWithBlock sorts with the given block", ^{
NSArray *a = [@"the quick brown fox jumped over the lazy dog" split:@" "];
NSArray *b = [a sortWithBlock:^id(id object) {
return @[ @([object length]), object ];
}];
NSLog(@"%@", b);
[[[a sortWithBlock:^id(id object) {
return @[ @([object length]), object ];
}] should] equal: [@"dog fox the the lazy over brown quick jumped" split:@" "]];
});
});

context(@"-indexOf", ^{
BOOL(^lookForSecond)(id i) = ^(id i) {
return [@"second" isEqualToString:i];
};

it(@"finds an index for an element in the array", ^{
[[@([sampleArray indexOf:lookForSecond]) should] equal:@1];
});

it(@"returns NSNotFound if the element isn't present", ^{
[[@([@[@"foo"] indexOf:lookForSecond]) should] equal:@(NSNotFound)];
});
});

it(@"-partition divides into even and odd", ^{
NSArray *evenOdd = [oneToTen partition:^BOOL(id object) {
return [object intValue] % 2 == 0;
}];
[[evenOdd[0] should] equal:@[@2, @4, @6, @8, @10]];
[[evenOdd[1] should] equal:@[@1, @3, @5, @7, @9]];
});

it(@"-uniq removes duplicate elements", ^{
NSMutableArray *dups = [NSMutableArray arrayWithArray:sampleArray];
[dups addObjectsFromArray:sampleArray];
[[[[dups uniq] sort] should] equal:[sampleArray sort]];
});
});


Expand Down