Reputation: 6323
I am using below code to check ary_navigationControllerViews array contains myclass object or not its working fine but i need with out for loop.I know we have method like containsObject but how to use in this situation. Is there any way to check this condition with out using for loop.
NSArray *ary_navigationControllerViews = [[NSArray alloc] initWithArray:[self.navigationController viewControllers]];
for(id obj_viewController in ary_navigationControllerViews) {
if([obj_viewController isKindOfClass:[myClass class]]) {
//some my code
return;
}
}
Upvotes: 1
Views: 2947
Reputation: 51374
NSPredicate does this kind of jobs a lot simpler.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY SELF.class.description == %@", [[myClass class] description]];
BOOL exists = [predicate evaluateWithObject:ary_navigationControllerViews];
if (exists) {
//some my code
return;
}
To get the view controller instance, you can use the following code.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self.class.description == %@", [[self class] description]];
NSArray *vcs = [ary_navigationControllerViews filteredArrayUsingPredicate:predicate];
if ([vcs count] > 0) {
id vc = [vcs objectAtIndex:0];
// Now vc is the view controller you are looking for
}
Upvotes: 12
Reputation: 44730
Or, based on Nekto's answer, you could also directly return the index like so:
NSArray *arr = [NSArray arrayWithObjects:[NSString stringWithFormat:@"test"], [NSNumber numberWithInt:10], [NSNull null], nil];
int index = [arr indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSNumber class]])
{
*stop = YES;
return YES;
}
return NO;
}];
if (index != NSNotFound)
{
NSLog(@"contains at %d", index);
}
Enjoy.
Upvotes: 3
Reputation: 119242
If you really can't use a for loop for this then you'll have to use a method like indexesOfObjectsPassingTest:
which applies a block to each object in the array and returns an NSIndexSet
of all the items in the array. You can then use this to return a new array of just the objects that pass your test:
check = ^ (id obj, NSUInteger idx, BOOL *stop)
{
return [obj isKindOfClass:[myClass class]];
};
NSIndexSet *objectsInMyClass = [[self.navigationController viewControllers] indexesOfObjectsPassingTest:check];
NSArray *filteredArray = [[self.navigationController viewControllers] objectsAtIndexes:objectsInMyClass];
You could then use makeObjectsPerformSelector
or similar to actually do your specific code.
Upvotes: 1
Reputation: 17877
You can use blocks:
NSArray *arr = [NSArray arrayWithObjects:[NSString stringWithFormat:@"test"], [NSNumber numberWithInt:10], [NSNull null], nil];
__block int index = NSNotFound;
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSNumber class]])
{
index = idx;
*stop = YES;
}
}];
if (index != NSNotFound)
{
NSLog(@"contains at %d", index);
}
For example, in your case:
[ary_navigationControllerViews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[myClass class]])
{
//some my code
*stop = YES;
}
}];
But I don't think that this will reduce complexity of yout code. Loops are the simplest one
Upvotes: 3