1

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;
        }
    }
9
  • 2
    Why can't you use a for loop? Commented Oct 17, 2011 at 10:10
  • For reducing complexity of code Commented Oct 17, 2011 at 10:16
  • 1
    A for-loop is as good/complex as something else. Commented Oct 17, 2011 at 10:20
  • @Akshay is right - look at the answers, then look at the code in your question - which one looks simpler? Commented Oct 17, 2011 at 10:24
  • I feel that a NSPredicate would be simpler than a for loop! Commented Oct 17, 2011 at 10:55

4 Answers 4

12

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
}
Sign up to request clarification or add additional context in comments.

3 Comments

I assumed Narayana wanted to do something with each specific object in the array that passed the test, but if not, yes, this is much simpler!
Clean and elegant! But it depends on the premise of classes returning a unique description (which doesn't have to be the case)
I have an array of items in which I am searching for object. The equality goes by address of objects, and this predicate I have to provide it to the NSFetchedResultsController. So, I cannot use blocks. I am trying something like this: NSPredicate *taskComponentsPredicate = [NSPredicate predicateWithFormat:@"ANY %@ == self",[[[self taskRegisterObject] componentsCollection] allObjects]]; I have dumped the values and manually checked, the objects exists in array, but it is not returned by predicates. I somehow feel there is something wrong am trying to get, cannot make out what. Help!
3

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

Comments

3

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.

3 Comments

Why do you copy+paste my answer? You didn't add any significant changes
Hey Nekto, I changed the used method to indexOfObjectPassingTest: which returns the index directly without the need for a __block var. I didn't want to make it seem as if I rip off your answer. I've added an attribution, I hope that's OK with you.
Ok, didn't notice all the changes. TY
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.