Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

arrays: firstN, initial, initialN, last, lastN, rest, restN. also mad…

…e first and last more robust
  • Loading branch information...
commit 354df875027a48437ac7595e5ec0ca8f3e802da7 1 parent 9763295
@petejkim authored
View
11 README.md
@@ -42,12 +42,15 @@ Underscore.cocoa is a utility-belt library for Objective-C & Cocoa that provides
### Arrays
✓ first
-× initial
-× last
-× rest
+✓ firstN
+✓ initial
+✓ initialN
+✓ last
+✓ lastN
+✓ rest
+✓ restN
× compact
× flatten
-× without
× union
× intersection
× difference
View
130 spec/ArraysSpec.m
@@ -20,6 +20,10 @@
specify(@"chained", ^{
expect(_(arr).chain().first().value()).toEqual(@"foo");
});
+
+ it(@"can handle exceptional cases", ^{
+ expect(_.first(_a(nil))).toBeNil();
+ });
});
describe(@"firstN", ^{
@@ -34,6 +38,132 @@
specify(@"chained", ^{
expect(_(arr).chain().firstN(2).value()).toEqual(_a(@"foo", @"bar"));
});
+
+ it(@"can handle exceptional cases", ^{
+ expect(_.firstN(arr, 5)).toEqual(arr);
+ expect(_.firstN(_a(nil), 2)).toEqual(_a(nil));
+ });
+});
+
+describe(@"initial", ^{
+ specify(@"functional style", ^{
+ expect(_.initial(arr)).toEqual(_a(@"foo", @"bar", @"baz"));
+ });
+
+ specify(@"object-oriented style", ^{
+ expect(_(arr).initial()).toEqual(_a(@"foo", @"bar", @"baz"));
+ });
+
+ specify(@"chained", ^{
+ expect(_(arr).chain().initial().value()).toEqual(_a(@"foo", @"bar", @"baz"));
+ });
+
+ it(@"can handle exceptional cases", ^{
+ expect(_.initial(_a(@"foo"))).toEqual(_a(nil));
+ expect(_.initial(_a(nil))).toEqual(_a(nil));
+ });
+});
+
+describe(@"initialN", ^{
+ before(^{
+ arr = _a(@"foo", @"bar", @"baz", @"qux", @"wiz");
+ });
+
+ specify(@"functional style", ^{
+ expect(_.initialN(arr, 2)).toEqual(_a(@"foo", @"bar", @"baz"));
+ });
+
+ specify(@"object-oriented style", ^{
+ expect(_(arr).initialN(2)).toEqual(_a(@"foo", @"bar", @"baz"));
+ });
+
+ specify(@"chained", ^{
+ expect(_(arr).chain().initialN(2).value()).toEqual(_a(@"foo", @"bar", @"baz"));
+ });
+
+ it(@"can handle exceptional cases", ^{
+ expect(_.initialN(_a(@"foo"), 2)).toEqual(_a(nil));
+ expect(_.initialN(_a(nil), 2)).toEqual(_a(nil));
+ });
+});
+
+describe(@"last", ^{
+ specify(@"functional style", ^{
+ expect(_.last(arr)).toEqual(@"qux");
+ });
+
+ specify(@"object-oriented style", ^{
+ expect(_(arr).last()).toEqual(@"qux");
+ });
+
+ specify(@"chained", ^{
+ expect(_(arr).chain().last().value()).toEqual(@"qux");
+ });
+
+ it(@"can handle exceptional cases", ^{
+ expect(_.last(_a(nil))).toBeNil();
+ });
+});
+
+describe(@"lastN", ^{
+ specify(@"functional style", ^{
+ expect(_.lastN(arr, 2)).toEqual(_a(@"baz", @"qux"));
+ });
+
+ specify(@"object-oriented style", ^{
+ expect(_(arr).lastN(2)).toEqual(_a(@"baz", @"qux"));
+ });
+
+ specify(@"chained", ^{
+ expect(_(arr).chain().lastN(2).value()).toEqual(_a(@"baz", @"qux"));
+ });
+
+ it(@"can handle exceptional cases", ^{
+ expect(_.lastN(arr, 5)).toEqual(arr);
+ expect(_.lastN(_a(nil), 2)).toEqual(_a(nil));
+ });
+});
+
+describe(@"rest", ^{
+ specify(@"functional style", ^{
+ expect(_.rest(arr)).toEqual(_a(@"bar", @"baz", @"qux"));
+ });
+
+ specify(@"object-oriented style", ^{
+ expect(_(arr).rest()).toEqual(_a(@"bar", @"baz", @"qux"));
+ });
+
+ specify(@"chained", ^{
+ expect(_(arr).chain().rest().value()).toEqual(_a(@"bar", @"baz", @"qux"));
+ });
+
+ it(@"can handle exceptional cases", ^{
+ expect(_.rest(_a(@"foo"))).toEqual(_a(nil));
+ expect(_.rest(_a(nil))).toEqual(_a(nil));
+ });
+});
+
+describe(@"restN", ^{
+ before(^{
+ arr = _a(@"foo", @"bar", @"baz", @"qux", @"wiz");
+ });
+
+ specify(@"functional style", ^{
+ expect(_.restN(arr, 2)).toEqual(_a(@"baz", @"qux", @"wiz"));
+ });
+
+ specify(@"object-oriented style", ^{
+ expect(_(arr).restN(2)).toEqual(_a(@"baz", @"qux", @"wiz"));
+ });
+
+ specify(@"chained", ^{
+ expect(_(arr).chain().restN(2).value()).toEqual(_a(@"baz", @"qux", @"wiz"));
+ });
+
+ it(@"can handle exceptional cases", ^{
+ expect(_.restN(_a(@"foo", @"bar"), 2)).toEqual(_a(nil));
+ expect(_.restN(_a(nil), 2)).toEqual(_a(nil));
+ });
});
SpecEnd
View
6 src/Underscore.h
@@ -19,7 +19,13 @@
#pragma mark - Arrays
@property (nonatomic, readonly) Underscore *(^first)(void);
+@property (nonatomic, readonly) Underscore *(^last)(void);
+@property (nonatomic, readonly) Underscore *(^initial)(void);
+@property (nonatomic, readonly) Underscore *(^rest)(void);
+@property (nonatomic, readonly) Underscore *(^initialN)(NSUInteger n);
+@property (nonatomic, readonly) Underscore *(^restN)(NSUInteger n);
@property (nonatomic, readonly) Underscore *(^firstN)(NSUInteger n);
+@property (nonatomic, readonly) Underscore *(^lastN)(NSUInteger n);
#pragma mark - Utility
View
100 src/Underscore.m
@@ -128,7 +128,7 @@ + (Underscore *)underscoreWithObject:(id)object {
- (Underscore *(^)(void))first {
id block = ^Underscore * {
- if([self.object isKindOfClass:[NSArray class]]) {
+ if([self.object isKindOfClass:[NSArray class]] && [self.object count] > 0) {
self.object = [self.object objectAtIndex:0];
} else {
self.object = nil;
@@ -138,13 +138,105 @@ + (Underscore *)underscoreWithObject:(id)object {
return [[block copy] autorelease];
}
+- (Underscore *(^)(void))last {
+ id block = ^Underscore * {
+ if([self.object isKindOfClass:[NSArray class]] && [self.object count] > 0) {
+ self.object = [self.object lastObject];
+ } else {
+ self.object = nil;
+ }
+ return self;
+ };
+ return [[block copy] autorelease];
+}
+
+- (Underscore *(^)(void))initial {
+ id block = ^Underscore * {
+ if([self.object isKindOfClass:[NSArray class]]) {
+ NSUInteger size = [self.object count];
+ if(size > 1) {
+ self.object = [self.object subarrayWithRange:NSMakeRange(0, size - 1)];
+ return self;
+ }
+ }
+ self.object = [NSArray array];
+ return self;
+ };
+ return [[block copy] autorelease];
+}
+
+- (Underscore *(^)(void))rest {
+ id block = ^Underscore * {
+ if([self.object isKindOfClass:[NSArray class]]) {
+ NSUInteger size = [self.object count];
+ if(size > 1) {
+ self.object = [self.object subarrayWithRange:NSMakeRange(1, size - 1)];
+ return self;
+ }
+ }
+ self.object = [NSArray array];
+ return self;
+ };
+ return [[block copy] autorelease];
+}
+
+- (Underscore *(^)(NSUInteger))initialN {
+ id block = ^Underscore *(NSUInteger n) {
+ if([self.object isKindOfClass:[NSArray class]]) {
+ NSUInteger size = [self.object count];
+ if(size > n) {
+ self.object = [self.object subarrayWithRange:NSMakeRange(0, size - n)];
+ return self;
+ }
+ }
+ self.object = [NSArray array];
+ return self;
+ };
+ return [[block copy] autorelease];
+}
+
+- (Underscore *(^)(NSUInteger))restN {
+ id block = ^Underscore *(NSUInteger n) {
+ if([self.object isKindOfClass:[NSArray class]]) {
+ NSUInteger size = [self.object count];
+ if(size > n) {
+ self.object = [self.object subarrayWithRange:NSMakeRange(n, size - n)];
+ return self;
+ }
+ }
+ self.object = [NSArray array];
+ return self;
+ };
+ return [[block copy] autorelease];
+}
+
- (Underscore *(^)(NSUInteger))firstN {
id block = ^Underscore *(NSUInteger n) {
if([self.object isKindOfClass:[NSArray class]]) {
- self.object = [self.object subarrayWithRange:NSMakeRange(0, n)];
- } else {
- self.object = [NSArray array];
+ NSUInteger size = [self.object count];
+ if(size > 0) {
+ self.object = [self.object subarrayWithRange:NSMakeRange(0, MIN(n, size))];
+ return self;
+ }
+ }
+ self.object = [NSArray array];
+ return self;
+ };
+ return [[block copy] autorelease];
+}
+
+- (Underscore *(^)(NSUInteger))lastN {
+ id block = ^Underscore *(NSUInteger n) {
+ if([self.object isKindOfClass:[NSArray class]]) {
+ NSUInteger size = [self.object count];
+ if(size > 0) {
+ NSUInteger startIndex = MAX((NSInteger)[self.object count] - (NSInteger)n, 0);
+ NSUInteger length = MIN(n, size - startIndex);
+ self.object = [self.object subarrayWithRange:NSMakeRange(startIndex, length)];
+ return self;
+ }
}
+ self.object = [NSArray array];
return self;
};
return [[block copy] autorelease];
View
6 src/UnderscoreFunctional.h
@@ -16,7 +16,13 @@
#pragma mark - Arrays
@property (nonatomic, readonly) id(^first)(NSArray *array);
+@property (nonatomic, readonly) id(^last)(NSArray *array);
+@property (nonatomic, readonly) NSArray *(^initial)(NSArray *array);
+@property (nonatomic, readonly) NSArray *(^rest)(NSArray *array);
+@property (nonatomic, readonly) NSArray *(^initialN)(NSArray *array, NSUInteger n);
+@property (nonatomic, readonly) NSArray *(^restN)(NSArray *array, NSUInteger n);
@property (nonatomic, readonly) NSArray *(^firstN)(NSArray *array, NSUInteger n);
+@property (nonatomic, readonly) NSArray *(^lastN)(NSArray *array, NSUInteger n);
#pragma mark - Utility
View
42 src/UnderscoreFunctional.m
@@ -50,6 +50,41 @@ + (void)initialize {
return [[block copy] autorelease];
}
+- (id(^)(NSArray *))last {
+ id block = ^id(NSArray *array) {
+ return _(array).last();
+ };
+ return [[block copy] autorelease];
+}
+
+- (NSArray *(^)(NSArray *))initial {
+ id block = ^id(NSArray *array) {
+ return _(array).initial();
+ };
+ return [[block copy] autorelease];
+}
+
+- (NSArray *(^)(NSArray *))rest {
+ id block = ^id(NSArray *array) {
+ return _(array).rest();
+ };
+ return [[block copy] autorelease];
+}
+
+- (NSArray *(^)(NSArray *, NSUInteger))initialN {
+ id block = ^id(NSArray *array, NSUInteger n) {
+ return _(array).initialN(n);
+ };
+ return [[block copy] autorelease];
+}
+
+- (NSArray *(^)(NSArray *, NSUInteger))restN {
+ id block = ^id(NSArray *array, NSUInteger n) {
+ return _(array).restN(n);
+ };
+ return [[block copy] autorelease];
+}
+
- (NSArray *(^)(NSArray *, NSUInteger))firstN {
id block = ^id(NSArray *array, NSUInteger n) {
return _(array).firstN(n);
@@ -57,6 +92,13 @@ + (void)initialize {
return [[block copy] autorelease];
}
+- (NSArray *(^)(NSArray *, NSUInteger))lastN {
+ id block = ^id(NSArray *array, NSUInteger n) {
+ return _(array).lastN(n);
+ };
+ return [[block copy] autorelease];
+}
+
#pragma mark - Utility
- (void(^)(NSUInteger, id))times {
View
6 src/UnderscoreUnchained.h
@@ -23,7 +23,13 @@
#pragma mark - Arrays
@property (nonatomic, readonly) id(^first)(void);
+@property (nonatomic, readonly) id(^last)(void);
+@property (nonatomic, readonly) NSArray *(^initial)(void);
+@property (nonatomic, readonly) NSArray *(^rest)(void);
+@property (nonatomic, readonly) NSArray *(^initialN)(NSUInteger n);
+@property (nonatomic, readonly) NSArray *(^restN)(NSUInteger n);
@property (nonatomic, readonly) NSArray *(^firstN)(NSUInteger n);
+@property (nonatomic, readonly) NSArray *(^lastN)(NSUInteger n);
#pragma mark - Utility
View
42 src/UnderscoreUnchained.m
@@ -62,6 +62,41 @@ + (UnderscoreUnchained *)underscoreUnchainedWithObject:(id)object {
return [[block copy] autorelease];
}
+- (id(^)(void))last {
+ id block = ^id {
+ return self.chain().last().value();
+ };
+ return [[block copy] autorelease];
+}
+
+- (NSArray *(^)(void))initial {
+ id block = ^NSArray * {
+ return self.chain().initial().value();
+ };
+ return [[block copy] autorelease];
+}
+
+- (NSArray *(^)(void))rest {
+ id block = ^NSArray * {
+ return self.chain().rest().value();
+ };
+ return [[block copy] autorelease];
+}
+
+- (NSArray *(^)(NSUInteger))initialN {
+ id block = ^NSArray *(NSUInteger n) {
+ return self.chain().initialN(n).value();
+ };
+ return [[block copy] autorelease];
+}
+
+- (NSArray *(^)(NSUInteger))restN {
+ id block = ^NSArray *(NSUInteger n) {
+ return self.chain().restN(n).value();
+ };
+ return [[block copy] autorelease];
+}
+
- (NSArray *(^)(NSUInteger))firstN {
id block = ^NSArray *(NSUInteger n) {
return self.chain().firstN(n).value();
@@ -69,6 +104,13 @@ + (UnderscoreUnchained *)underscoreUnchainedWithObject:(id)object {
return [[block copy] autorelease];
}
+- (NSArray *(^)(NSUInteger))lastN {
+ id block = ^NSArray *(NSUInteger n) {
+ return self.chain().lastN(n).value();
+ };
+ return [[block copy] autorelease];
+}
+
#pragma mark - Utility
- (void(^)(id))times {
Please sign in to comment.
Something went wrong with that request. Please try again.