6

我有一个可变的布尔值数组,我想检查是否有任何值是 YES。

目前我正在创建另一个数组,它总是像这样的 ALL False;

 [MyArray addObject:[NSNumber numberWithBool:switchInput]];
 [MyAllNoArray addObject:[NSNumber numberWithBool:NO]];

用户做了一些操作,MyArray 中的一些对象可能变为 YES,然后我使用下面的内容来查看 ANY 是否为真。

if([MyArray isEqualToArray:MyAllNoArray])

我只是想知道是否有更好的方法(这种方法似乎很浪费)?

我考虑过一个计数器,每次其中一个对象发生变化时,计数器都会上升或下降(取决于更改为 YES 或 NO),如果计数器为 0,那么数组也是如此。但我只是想在我缺少的 IF 语句中可能有更好的方法。

4

6 回答 6

11

我认为一个更简单的解决方案是:

NSArray *bools = @[@(NO),@(NO), @(YES)];
    if ([bools containsObject:@(YES)]) {
        // do your magic here
    }

如果您只需要检查是否存在,则循环和块将是一种过度杀伤力。

于 2013-09-04T17:24:32.753 回答
1
NSArray *myArray;

__block bool hasTrue = NO;
[myArray enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
    if (num.boolValue) {
        hasTrue = YES;
        *stop = YES;
    }
}];

if (hasTrue)
    NSLog(@"there is a true value in myArray.");
else
    NSLog(@"there is not true value in myArray.");

或者把它变成一个方法:

- (BOOL)doesMyArrayHaveTrue {
    NSArray *myArray;

    __block bool hasTrue = NO;
    [myArray enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
        if (num.boolValue) {
            hasTrue = YES;
            *stop = YES;
        }
    }];

    return hasTrue;
}

或者......我还没有尝试过,但我认为它应该可以工作:

NSNumber * max = [myArray valueForKeyPath:@"@max.self"];
if (max.boolValue)
    NSLog(@"there is a true values.");
else
    NSLog(@"there is not a true value.");
于 2013-09-04T16:47:03.420 回答
1

最简单的方法是使用containsObject:@(YES).

解释

如果您查看 NSArray 文档,它会说

containsObject:返回一个布尔值,指示给定对象是否存在于数组中。

  • (BOOL) 包含对象:(id) 一个对象

讨论

此方法通过向数组的每个对象发送 isEqual: 消息(并将 anObject 作为参数传递给每个 isEqual: 消息)来确定数组中是否存在anObject。

所以containsObject:@(YES)应该做的伎俩

于 2013-09-04T17:33:30.617 回答
0

与随机答案几乎相同,但没有块。

bool allFalse = true;
for(NSNumber *number in MyArray)
{
    if([number boolValue])
    {
        allFalse = false;
        break;
    }
}

if(!allFalse)
{
    ...
}
于 2013-09-04T16:50:23.560 回答
0
NSNumber* yesBool = [NSNumber numberWithBool:YES];
BOOL foundYes = NO;
for (NSNumber* num in MyArray) {
    if ([num isEqualToNumber:yesBool) {
        foundYes = YES;
        break;
    }
}

对于没有某种“分数”的测试,您不能做得更好(*),尽管如果您选择“保持分数”,您的计数器方案无疑会更好。

(*) using 是否isEqualToNumber比简单的 testing 更有效还是有争议的boolValue

于 2013-09-04T16:55:16.750 回答
0

这里有很多好的答案,@Arcanfel 和@rr1g0 的简单使用建议containsObject:非常优雅和简单。

但是,许多已回答该主题的受人尊敬的同事都遗漏了一个重要的选择-基于谓词的解决方案。因此,为了完整起见:

NSArray *data = @[@(NO), @(YES), @(NO)];

NSPredicate *hasYesPred = [NSPredicate predicateWithFormat: @"SUBQUERY(SELF, $s, $s == %@).@count > 0", @(YES)];

BOOL hasYes = [hasYesPred evaluateWithObject: data];

这里的想法是子查询构造一个等于 的对象数组@(YES),然后我们对其进行计数,如果它是正数,我们知道数组中至少有一个真正的布尔值。

这种方法显然可以扩展到其他类型的数字——例如,确定一个数组中是否至少有一个负数。

于 2013-09-04T19:09:14.807 回答