Skip to content

Commit

Permalink
#20 map, flatMap, and flatten work on one level
Browse files Browse the repository at this point in the history
- Map and Flatten Enumerators are no longer recursive.
- Added [Callable identity] to use in testing flatMap.
- Removed testMapLiftsMappables - map shouldn’t lift mappables
  • Loading branch information
frankleonrose committed Mar 3, 2015
1 parent 00f7cb9 commit 2e2fe80
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 17 deletions.
2 changes: 2 additions & 0 deletions src/main/Callables.h
Expand Up @@ -5,6 +5,8 @@ typedef NSNumber *(^CALLABLE_TO_NUMBER)(id);
typedef NSString *(^ACCUMULATOR_TO_STRING)(id, id);

@interface Callables : NSObject
+ (id (^)(id))identity;

+ (NSString * (^)(NSString *))toUpperCase;

+ (NSString * (^)(NSString *, NSString *))appendString;
Expand Down
4 changes: 4 additions & 0 deletions src/main/Callables.m
@@ -1,6 +1,10 @@
#import "Callables.h"

@implementation Callables
+ (id (^)(id))identity {
return [^(id item) { return item; } copy];
}

+ (NSString * (^)(NSString *))toUpperCase {
return [^(NSString *item) { return item.uppercaseString; } copy];
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/enumerators/FlattenEnumerator.m
Expand Up @@ -20,7 +20,7 @@ - (id)nextObject {
while((item = [currentEnumerator nextObject]) == nil) {
id nextItem = [enumerator nextObject];
if ([nextItem respondsToSelector:@selector(toEnumerator)]) {
currentEnumerator = [FlattenEnumerator withEnumerator:[nextItem toEnumerator]];
currentEnumerator = [nextItem toEnumerator];
continue;
}
return nextItem;
Expand Down
2 changes: 1 addition & 1 deletion src/main/enumerators/MapEnumerator.m
Expand Up @@ -20,7 +20,7 @@ + (NSEnumerator *)withEnumerator:(NSEnumerator *)enumerator andFunction:(id (^)(

- (id)nextObject {
id item = [enumerator nextObject];
return (item == nil) ? nil : [item conformsToProtocol:@protocol(Mappable)] ? [item map:func] : func(item);
return (item == nil) ? nil : func(item);
}


Expand Down
8 changes: 5 additions & 3 deletions src/test-unit/NSArrayTest.m
Expand Up @@ -39,16 +39,18 @@ - (void)testFlatMap {
array(@"one", @"two", nil),
array(@"three", @"four", nil),
nil);
assertThat([items flatMap:[Callables toUpperCase]], hasItems(@"ONE", @"TWO", @"THREE", @"FOUR", nil));
assertThat([items flatMap:[Callables identity]], hasItems(@"one", @"two", @"three", @"four", nil));
}

-(void)testFlatMapSupportsNDepthSequences {
-(void)testFlatMapFlattensOnlyOneLevel {
NSArray *items = array(
@"one",
array(@"two", @"three", nil),
array(array(@"four", nil), nil),
nil);
assertThat([items flatMap:[Callables toUpperCase]], hasItems(@"ONE", @"TWO", @"THREE", @"FOUR", nil));
NSArray *flatMapped = [items flatMap:[Callables identity]];
assertThat(flatMapped, hasItems(@"one", @"two", @"three", nil));
assertThat([flatMapped objectAtIndex:3], hasItems(@"four", nil));
}

-(void)testFlattenResolvesOptions {
Expand Down
34 changes: 22 additions & 12 deletions src/test-unit/SequenceTest.m
Expand Up @@ -64,7 +64,7 @@ - (void)testFlatMap {
sequence(@"one", [None none], nil),
sequence(@"three", @"four", nil),
nil);
assertThat([[items flatMap:[Callables toUpperCase]] asArray], hasItems(@"ONE", @"THREE", @"FOUR", nil));
assertThat([[items flatMap:[Callables identity]] asArray], hasItems(@"one", [None none], @"three", @"four", nil));

Sequence *numbers = sequence(@1, @2, @3, @4, nil);
Sequence *flattenedNumbers = [numbers flatMap:^(NSNumber *number) {
Expand Down Expand Up @@ -104,7 +104,17 @@ - (void)testGroupByHandlesNilKeyAsUniqueGroup {
}];
assertThatInt([[groups asArray] count], equalToInt(3));
assertThat([groups first], hasItems(@"one", nil));
}

- (void)testGroupByGeneratesMappableGroups {
Sequence *groups = [sequence(@"one", @"two", @"three", @"four", @"five", @"six", @"seven", nil) groupBy:^(NSString *item) {
return [NSNumber numberWithInt:item.length];
}];
Sequence *counts = [groups map:^id(Group *g) {
return @([[g asArray] count]);
}];
assertThat(counts, hasItems(@3, @2, @2, nil));
assertThatInt([[counts asArray] count], equalToInt(3));
}

- (void)testGrouped {
Expand Down Expand Up @@ -137,14 +147,6 @@ - (void)testMap {
assertThat([doubled asArray], hasItems(@2, @4, @6, nil));
}

- (void)testMapLiftsMappables {
Sequence *lazy = sequence(@[@1], option(@2), [None none], nil);
Sequence *doubled = [lazy map:^(NSNumber *item) {
return @([item intValue] * 2);
}];
assertThat([doubled asArray], hasItems(@[@2], option(@4), [None none], nil));
}

- (void)testMapDoesNotRetainBlocks {
self.checkRetained = @0;
Sequence *lazy = sequence(@1, @2, @3, nil);
Expand All @@ -163,6 +165,14 @@ - (void)testMapWithIndex {
assertThat([indexes asArray], hasItems(@0, @1, @2, nil));
}

- (void)testMapWithIndexNested {
Sequence *lazy = sequence(@"one", @"two", @"three", sequence(@"nestedOne", @"nestedTwo", nil), nil);
Sequence *indexes = [lazy mapWithIndex:^(id item, NSInteger index) {
return @(index);
}];
assertThat([indexes asArray], hasItems(@0, @1, @2, @3, nil));
}

- (void)testMerge {
Sequence *result1 = [sequence(@"1", @"2", nil) merge:sequence(@"3", @"4", @"5", nil)];
assertThat([result1 asArray], hasItems(@"1", @"3", @"2", @"4", @"5", nil));
Expand Down Expand Up @@ -315,12 +325,12 @@ - (void)testNonForwardBehaviour {
assertThat([items take:1], hasItems(@"one", nil));
assertThat([items take:1], hasItems(@"one", nil));

Sequence *flattenable = sequence(sequence(@"one", nil), @"two", nil);
Sequence *flattenable = sequence(@"one", @"two", nil);
assertThat([flattenable flatMap:^(NSString *item) {
return [item substringFromIndex:1];
return option([item substringFromIndex:1]);
}], hasItems(@"ne", @"wo", nil));
assertThat([flattenable flatMap:^(NSString *item) {
return [item substringFromIndex:1];
return option([item substringFromIndex:1]);
}], hasItems(@"ne", @"wo", nil));
}

Expand Down

0 comments on commit 2e2fe80

Please sign in to comment.