diff --git a/Classes/NSArray+ObjectiveSugar.h b/Classes/NSArray+ObjectiveSugar.h index ea7b5a0..08c667a 100644 --- a/Classes/NSArray+ObjectiveSugar.h +++ b/Classes/NSArray+ObjectiveSugar.h @@ -31,6 +31,15 @@ */ - (id)sample; +/** + Take random `numberOfElements` out of the array, or the maximum amount of + elements if it is less. + + @param Number of random elements to take from array + @return An array of elements + */ +- (NSArray *)sample:(NSUInteger)numberOfElements; + /// Alias for -sample - (id)anyObject; diff --git a/Classes/NSArray+ObjectiveSugar.m b/Classes/NSArray+ObjectiveSugar.m index b2c2503..9ef3278 100644 --- a/Classes/NSArray+ObjectiveSugar.m +++ b/Classes/NSArray+ObjectiveSugar.m @@ -21,6 +21,19 @@ - (id)sample { return self[index]; } +- (NSArray *)sample:(NSUInteger)numberOfElements { + if (numberOfElements > self.count) { + numberOfElements = self.count; + } + NSMutableArray *array = [NSMutableArray arrayWithArray:self]; + for (NSUInteger i = 0; i < numberOfElements; i++) { + NSInteger size = array.count - i; + NSInteger r = (arc4random() % size) + i; + [array exchangeObjectAtIndex:i withObjectAtIndex:r]; + } + return [array subarrayWithRange:NSMakeRange(0, numberOfElements)]; +} + - (id)objectForKeyedSubscript:(id)key { if ([key isKindOfClass:[NSString class]]) return [self subarrayWithRange:[self rangeFromString:key]]; diff --git a/Example/ObjectiveSugarTests/NSArrayCategoriesTests.m b/Example/ObjectiveSugarTests/NSArrayCategoriesTests.m index f3628f8..e118767 100644 --- a/Example/ObjectiveSugarTests/NSArrayCategoriesTests.m +++ b/Example/ObjectiveSugarTests/NSArrayCategoriesTests.m @@ -29,6 +29,17 @@ NSArray *emptyArray = @[]; [emptyArray.sample shouldBeNil]; }); + + it(@"-sample: returns an array of random elements with given count", ^{ + NSArray *result = [sampleArray sample:2]; + [[result should] haveCountOf:2]; + [[sampleArray should] containObjectsInArray:result]; + }); + + it(@"-sample: returns an array of maximum amount when it is less than given count" , ^{ + [[[sampleArray sample:12] should] haveCountOf:3]; + [[[sampleArray sample:-1] should] haveCountOf:3]; + }); context(@"Iterating using block", ^{