问题
I have a mutable array of Boolean values and I want to check to see if ANY of the values are YES.
At present I am creating another array alongside this one which is always ALL False like so;
[MyArray addObject:[NSNumber numberWithBool:switchInput]];
[MyAllNoArray addObject:[NSNumber numberWithBool:NO]];
The user does some bits and the some of the objects in MyArray may become YES, I then use the below to see if ANY are true or not.
if([MyArray isEqualToArray:MyAllNoArray])
I am just wondering if there is a better way (this way seems wasteful)?
I have thought about a counter, each time one of the objects changes the counter goes up or down (depending on changing to YES or NO), if the counter is 0 then so is the array. But I am just thinking there may be a better way within an IF statement that I am missing.
回答1:
I think a simpler solution would be this:
NSArray *bools = @[@(NO),@(NO), @(YES)];
if ([bools containsObject:@(YES)]) {
// do your magic here
}
Loops and blocks would be an overkill if you just need to check for presence.
回答2:
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.");
Or turn it into a method:
- (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;
}
Or...I haven't tried this yet but I think it should work:
NSNumber * max = [myArray valueForKeyPath:@"@max.self"];
if (max.boolValue)
NSLog(@"there is a true values.");
else
NSLog(@"there is not a true value.");
回答3:
The easiest way is to use containsObject:@(YES)
.
Explanation
If you check the NSArray documentation it says
containsObject: Returns a Boolean value that indicates whether a given object is present in the array.
- (BOOL)containsObject:(id)anObject
Discussion
This method determines whether anObject is present in the array by sending an isEqual: message to each of the array’s objects (and passing anObject as the parameter to each isEqual: message).
So containsObject:@(YES)
should do the trick
回答4:
Pretty much the same answer as random, but without blocks.
bool allFalse = true;
for(NSNumber *number in MyArray)
{
if([number boolValue])
{
allFalse = false;
break;
}
}
if(!allFalse)
{
...
}
回答5:
NSNumber* yesBool = [NSNumber numberWithBool:YES];
BOOL foundYes = NO;
for (NSNumber* num in MyArray) {
if ([num isEqualToNumber:yesBool) {
foundYes = YES;
break;
}
}
You can't do much (*) better than that for a test without some sort of "score", though your counter scheme is no doubt better, should you choose to "keep score".
(*) It's debatable whether using isEqualToNumber
is more or less efficient than simply testing boolValue
.
回答6:
Many good answers here, and @Arcanfel and @rr1g0's suggestion of simply using containsObject:
is really elegant and simple.
The many esteemed colleagues who have answered the thread have left out an important option, though - a predicate-based solution. So here goes, in the interest of completeness:
NSArray *data = @[@(NO), @(YES), @(NO)];
NSPredicate *hasYesPred = [NSPredicate predicateWithFormat: @"SUBQUERY(SELF, $s, $s == %@).@count > 0", @(YES)];
BOOL hasYes = [hasYesPred evaluateWithObject: data];
The idea here is that the subquery constructs an array of objects that are equal to @(YES)
, then we take the count of that, and if it is positive, we know that there is at least one true boolean value in the array.
This approach obviously can be extended to other types of numbers - to determine if there is at least one negative number in an array, for instance.
来源:https://stackoverflow.com/questions/18619419/in-objective-c-check-an-array-of-boolean-values-and-see-if-at-least-one-is-yes