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"];
}
}
上面是我在应用程序中使用的代码,用于从存储在plist中的两个类别之一(在数组中,第一行是category,第二行是quote)生成随机报价。但是,它似乎倾向于重复已经显示的内容。我希望它有一个偏好设置(但不是排他性地)显示以前没有显示的显示内容。
答案 0 :(得分:1)
您的问题是算法问题。您想要的是看起来似乎随机但更统一的数字序列。
您要寻找的被称为low-discrepancy sequence。一种简单的形式是“洗牌袋”,通常在游戏开发中使用,如here或here所述。
使用洗牌袋,您基本上会生成所有索引(例如0 1 2 3 4 5),对它们进行洗牌(例如2 3 5 1 0 4),然后按此顺序显示元素。最后,您将生成另一个序列(例如4 1 0 2 3 5)。请注意,同一元素有可能在序列中出现两次,尽管这种情况很少见。例如。在这种情况下,“ 4”是重复的,因为完整序列是2 3 5 1 0 4 4 1 0 2 3 5。
arc4random()
在Apple平台上是很好的PRNG,因此它不会给您“低差异序列”。但是:您可以将其用作生成“低差异序列”的原语,也可以将其用作创建随机播放袋实现的原语。