Reputation: 387
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"category == %@", selectedCategory];
NSArray *filteredArray = [self.Quotes filteredArrayUsingPredicate:predicate];
// Get total number in filtered array
int array_tot = (int)[filteredArray count];
// As a safeguard only get quote when the array has rows in it
if (array_tot > 0) {
// Get random index
int index = (arc4random() % array_tot);
// Get the quote string for the index
NSString *quote = [[filteredArray objectAtIndex:index] valueForKey:@"quote"];
// Display quote
self.quote_text.text = quote;
// Update row to indicate that it has been displayed
int quote_array_tot = (int)[self.Quotes count];
NSString *quote1 = [[filteredArray objectAtIndex:index] valueForKey:@"quote"];
for (int x=0; x < quote_array_tot; x++) {
NSString *quote2 = [[Quotes objectAtIndex:x] valueForKey:@"quote"];
if ([quote1 isEqualToString:quote2]) {
NSMutableDictionary *itemAtIndex = (NSMutableDictionary *)[Quotes objectAtIndex:x];
[itemAtIndex setValue:@"DONE" forKey:@"source"];
}
}
Above is the code I use in my app for generating a random quote from one of two categories stored in a plist (in arrays, where the first line is category, and second is quote). However, it seems to have a preference of repeating ones it's already shown. I'd prefer it have a preference (but not exclusively) show ones it hasn't shown before.
Upvotes: 0
Views: 50
Reputation: 6517
Your question is an algorithm question. What you want is a sequence of numbers that seems random but is more uniform.
What you are looking for is called a low-discrepancy sequence. A simple form of this is a "shuffle bag", often used in game development, as described here or here.
With a shuffle bag, you basically generate all the indices (e.g. 0 1 2 3 4 5), shuffle them (e.g. 2 3 5 1 0 4) and then display the elements in this order. At the end, you generate another sequence (e.g. 4 1 0 2 3 5). Note that it is possible that the same element appears twice in the sequence, although it is rare. E.g. in this case, the "4" is a duplicate, because the full sequence is 2 3 5 1 0 4 4 1 0 2 3 5.
arc4random()
is a good PRNG on Apple platforms, so it doesn't give you a "low discrepancy sequence". But: you can use it as a primitive to generate "low discrepancy sequences", you can also use it as a primitive to create a shuffle bag implementation.
Upvotes: 1