Getting a random object from NSArray without duplication
You could do this by making a mutable copy of the array, and after you make a random selection from that array, remove that same object. When you want to save the array, save the mutable array itself, so can resume where you left off when the app restarts. This little test app does that, and just logs the value of the random pick:
- (void)viewDidLoad {
[super viewDidLoad];
self.objArray = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17"];
self.mut = [self.objArray mutableCopy];
}
-(IBAction)pickNumber:(id)sender {
int index = arc4random_uniform(self.mut.count);
NSLog(@"%@", self.mut[index]);
[self.mut removeObjectAtIndex:index];
if (self.mut.count == 0) {
self.mut = [self.objArray mutableCopy];
NSLog(@"*******************");
}
}
As a starting point, you could shuffle your array:
+ (NSArray *)arrayByShufflingArray:(NSArray *)array
{
// Fisher-Yates algorithm
NSMutableArray *result = [array mutableCopy];
NSUInteger count = [result count];
for (NSInteger i = ((NSInteger) count) - 1; i > 0; i--) {
NSUInteger firstIndex = (NSUInteger)i;
NSUInteger secondIndex = arc4random() % (NSUInteger)(i + 1);
[result exchangeObjectAtIndex:firstIndex withObjectAtIndex:secondIndex];
}
return result;
}
Step through each shuffled element and when you get to the end, reshuffle.
It can still happen that an item is selected twice in a row when the last item of one shuffle is the same as the first item in the next shuffle. If you want to avoid this you'll have to add some additional code.