检查NSMutableArray是否包含int

时间:2014-11-01 13:46:58

标签: ios objective-c arrays nsmutablearray arc4random

我正在制作一个应用程序,询问用户一系列问题。提出的问题取决于产生的随机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

4 个答案:

答案 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。