tags:

views:

380

answers:

3

Here is my scenario: I have an array of dictionary items with 2 values.

array = (
    {
        id = 1;
        title = "Salon One";
    },
    {
        id = 2;
        title = "Salon Two";
    }
)

I'm not even sure if this is possible, but can I pass this array into a function and return an objects index based on a dictionary value?

- (int)getObjectIndex:(NSMutableArray *)array byName:(NSString *)theName{
    int index;

    /* Pseudo Code*/
    /*index = the index value in 'array' of objectForKey:@"title" = theName*/

    return index;
}
A: 

Of course it's possible, just loop through the array until you find the thing you're looking for

Paul Betts
+4  A: 

Why not?

- (NSInteger)getObjectIndex:(NSMutableArray *)array byName:(NSString *)theName {
    NSInteger idx = 0;
    for (NSDictionary* dict in array) {
        if ([[dict objectForKey:@"title"] isEqualToString:theName])
            return idx;
        ++idx;
    }
    return NSNotFound;
}

Note the slight difference in the signature (return type NSInteger vs int). This is necessary when using NSNotFound in 64 bit environments.

Nikolai Ruhe
+1 Beat me to it by 10 seconds!
Quinn Taylor
However, I'd suggest renaming the method `-indexOfObjectInArray:byTitle:` instead. Using "get" as the prefix in Cocoa implies return by reference.
Quinn Taylor
@Quinn: Absolutely, thanks for pointing that out.
Nikolai Ruhe
Wonderful. I had a for loop, but it wasn't in the for each form that you have it in. Still trying to get myself accustomed to the syntax.
rson
+5  A: 

If you want to go super-fancy with blocks introduced in Snow Leopard, you could do:

- (BOOL (^)(id obj, NSUInteger idx, BOOL *stop))blockTestingForTitle:(NSString*)theName {
    return [[^(id obj, NSUInteger idx, BOOL *stop) {
     if ([[obj objectForKey:@"title"] isEqualToString:theName]) {
      *stop = YES;
      return YES;
     }
     return NO;
    } copy] autorelease];
}

and then whenever you want to find the index of a dictionary in an array:

[array indexOfObjectPassingTest:[self blockTestingForTitle:@"Salon One"]]
Adrian
This strategy is better than enumerating the array yourself since it gives NSArray the chance to run in parallel.
Marc Charbonneau