Yet another little objective-C hack, for when you just want to count:
for (NSNumber * num in [@2 to:@4]) {
// do something with num
}
Here, [@2 to:@4]
is actually the same thing as @[@2, @3, @4]
.
Probably of little use, but very easy to write: all it takes is a method on NSNumber and a very small NSArray subclass. Here’s the one public method:
@interface NSNumber (ObjcRange)
// returns an array of the n + 1 NSIntegers between the receiver and `end_`, inclusive.
- (NSArray*) to:(NSNumber*)end_;
@end
And all it does is creating an small subclass of NSArray.
@implementation NSNumber (ObjcRange)
- (NSArray*) to:(NSNumber*)end_
{
return [[ObjcRange alloc] initWithNumbersFrom:[self integerValue] to:[end_ integerValue]];
}
@end
The trick is that NSArray doesn’t care where its objects are stored. They can actually be organized in a C array, a linked list, a tree, etc. The actual implementation even swaps its internal storage sometimes.
In fact, all that’s required to subclass NSArray is to override -count
and -objectAtIndex:
,
both of which can trivially be implemented just by knowing the start and end of our range:
@implementation ObjcRange
{
NSInteger _start, _end;
}
- (id)initWithNumbersFrom:(NSInteger)start_ to:(NSInteger)end_
{
self = [super init];
if(start_ < end_) {
_start = start_;
_end = end_;
} else {
_start = end_;
_end = start_;
}
return self;
}
- (NSUInteger)count
{
return _end - _start + 1;
}
- (id)objectAtIndex:(NSUInteger)index
{
return @(_start + (NSInteger)index);
}
@end
Here’s a github repo with the source. There’s probably much more to be done with it, feel free to hack away and let me know.