我正在制作一个应用程序,询问用户一系列问题。提出的问题取决于产生的随机int
。当使用int
时,我想将其添加到NSMutableArray
,然后在下次选择随机数时检查数组是否包含数字。我目前正在使用以下代码执行此操作:
- (void) selectQuestionNumber {
textNum = lowerBounds + arc4random() % (upperBounds - lowerBounds);
if ([previousQuestions containsObject:[NSNumber numberWithInt:textNum]]) {
[self selectQuestionNumber];
NSLog(@"The same question number appeared!");
} else {
questionLabel.text = [self nextQuestion];
[self questionTitleChange];
NSLog(@"New question made");
}
[previousQuestions addObject:[NSNumber numberWithInt:textNum]];
}
但是,代码NSLog(@"The same question number appeared!");
永远不会显示在控制台中,即使同一个问题会出现两次。
我的代码显然不起作用,那么我可以使用什么代码来检查NSMutable数组是否包含int
?
答案 0 :(得分:2)
您的问题可能不仅仅是在NSArray中检测NSNumbers的成员资格。可能需要大量尝试才能重复一组随机数。理论上,它可能不会重复,直到每个可能的值生成一次。对于大范围的法律价值,可能需要一段时间。
我建议记录每次传递时添加到数组中的值以及新值。
上面的代码总是会将新值添加到数组中,即使匹配也是如此,因此您的数组将会重复增长。如果不匹配,最好只将新数字添加到数组中。你可能也会更好地使用NSMutableSet而不是数组。 NSSets最多包含一个对象实例,它们的containsObject方法比NSArray快。
答案 1 :(得分:1)
原始解决方案(适用于数组和设置):
-(void)selectQuestionNumber
{
textNum = lowerBounds + arc4random() % (upperBounds - lowerBounds);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"intValue=%i",textNum];
NSArray *filteredArray = [previousQuestions filteredArrayUsingPredicate:predicate];
if ([filteredArray count]) {
[self selectQuestionNumber];
NSLog(@"The same question number appeared!");
} else {
questionLabel.text = [self nextQuestion];
[self questionTitleChange];
NSLog(@"New question made");
}
[previousQuestions addObject:[NSNumber numberWithInt:textNum]];
}
最佳解决方案,以及更好的性能,特别是使用mutableSet(根据Duncan C)。
-(void)selectQuestionNumber
{
textNum = lowerBounds + arc4random() % (upperBounds - lowerBounds);
if ([previousQuestions containsObject:[NSNumber numberWithInteger:textNum]]) {
[self selectQuestionNumber];
NSLog(@"The same question number appeared!");
} else {
questionLabel.text = [self nextQuestion];
[self questionTitleChange];
NSLog(@"New question made");
// And add the new number to mutableSet of mutableArray.
[previousQuestions addObject:[NSNumber numberWithInteger:textNum]];
}
}
答案 2 :(得分:0)
您可以使用NSMutableIndexSet,而不是使用NSArray。这与NSSet相同,仅使用NSUIntegers而不是对象。非常有用。
//during init
NSMutableIndexSet *tSet = [[NSMutableIndexSet alloc] init];
//...
//later in the code, in whatever loop you have on new values
NSUInteger newInt = lowerBounds + arc4random() % (upperBounds - lowerBounds);
if ([tSet containsIndex:newInt]){
//value already exists in the set
}
else {
//value does not exist, add it
[tSet addIndex:newInt];
}
答案 3 :(得分:-1)
NSMutableSet *myNumbers = [NSMutableSet Set]; // or NSMutableArray..
NSNumber *aNumber = [NSNumber numberWithInt:getRandomInt() ]; //let us say it returns 1.
[myNumbers addObject:aNumber];
-(BOOL)succesfullyAddNewUniqueRandomMember{
NSInteger randInt = getRandomInt(); //let us say it returns 1 again..
NSNumber *aSubsequentNumber = [NSNumber numberWithInt:randInt;
for (NSNumber *previousEntry in myNumbers){
if ([previousEntry isEqual:aSubsequentNumber]) return NO;
}
[myNumbers addObject:aSubsequentNumber];
return YES;
}
^这些对象是否相等(aNumber,aSubsequentNumber)?是
^他们是同一个对象吗?不,两个不同的NSNumber使用相等的整数。
NSSet也很乐意添加两者,因为它们不是同一个对象。
因此你需要循环并直接与每个前一个成员进行比较,NSSet的(已经包含的对象)过滤器不会起作用。
通过将其包装在 - (BOOL)类型方法中,我们可以用
重复它while(![self succesfullyAddNewUniqueRandomMember])
换句话说,在你的代码中
if ([previousQuestions containsObject:[NSNumber numberWithInt:textNum]])
总是返回NO,因为它正在比较NSNumber对象,而不是它们的integerValue。