繁体   English   中英

检查NSMutableArray是否包含int

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM