[英]Check if NSMutableArray contains an int
我正在制作一个向用户询问一系列问题的应用程序。 问的问题取决于产生的随机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
?
您的问题可能与检测NSArray中的NSNumbers成员身份不同。 重复一组随机数可能需要大量尝试。 从理论上讲,直到每个可能的值都生成一次才重复。 对于各种各样的法律价值,可能要花相当长的时间。
我建议记录每次通过时添加到数组的值以及新值。
上面的代码即使匹配也总是将新值添加到数组中,因此您的数组将随着重复项而增长。 如果新数字不匹配,最好只将新数字添加到数组中。 您也可能最好使用NSMutableSet而不是数组。 NSSet最多包含一个对象的一个实例,它们的containsObject方法比NSArray更快。
原始解决方案(适用于数组和集合):
-(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]];
}
}
可以使用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];
}
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。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.