Search code examples
objective-ckey-value-coding

Keypath for first element in embedded NSArray


This example is contrived, but it shows my point.

So, if I have an object graph like the following:

{
sex = male;
uid = 637650940;
work = ({
    employer = {
        id = 116420715044499;
        name = "Software Engineer";
    };
    "end_date" = "0000-00";
    "start_date" = "0000-00";
}, {
    employer = {
        id = 188733137832278;
        name = "Apple";
    };
});
},
//Some more objects

(This is an NSArray containing NSDictionarys that have an object of type NSArray).

The key field is work. I want a Key Path that will take the first object in the work array.

If I do this:

NSArray* work = [outerArrayObject objectForKey: @"work"];
id name = [work valueForKeyPath: @"employer.name"];

I get an array containing each name (In the above case, Software Engineer & Apple). Is there a collection operator or something to return the first object? Bonus points if you can develop a Key Path to sort each work by start_date also :)


Solution

  • Well to answer my own question, one way to do it is this:

    1) Define the following category

    @implementation NSArray (CustomKVOOperators)
    
    - (id) _firstForKeyPath: (NSString*) keyPath {
        NSArray* array = [self valueForKeyPath: keyPath];
        if( [array respondsToSelector: @selector(objectAtIndex:)] &&
            [array respondsToSelector: @selector(count)]) {
            if( [array count] )
                return [array objectAtIndex: 0];
            else
                return nil;
        }
        else {
            return nil;
        }
    }
    
    @end
    

    2) Use this KeyPath syntax

    NSArray* work = [outerArrayObject objectForKey: @"work"];
    id name = [work valueForKeyPath: @"@first.employer.name"];
    

    Thanks to this clever person.