2012-08-21 4 views
11

Este ejemplo es artificial, pero muestra mi punto.Keypath para el primer elemento en NSArray incorporado

Por lo tanto, si tengo un gráfico de objetos como el siguiente:

{ 
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 

(Esta es una NSArray contiene NSDictionarys que tienen un objeto de tipo NSArray).

El campo clave es work. Quiero un Key Path que tomará el primer objeto en la matriz work.

Si hago esto:

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

consigo una matriz que contiene cada nombre (En el caso anterior, ingeniero de software de Apple &). ¿Hay un operador de recolección o algo para devolver el primer objeto? Los puntos de bonificación si se puede desarrollar una Ruta de la clave para ordenar cada obra por fecha_inicial también :)

Respuesta

15

Bueno, para responder a mi propia pregunta, una forma de hacerlo es la siguiente:

1) Definir la siguiente categoría

@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) Utilice esta sintaxis KeyPath

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

Gracias a this clever person.

+0

En el caso de '' 'outerArrayObject''' es que su padre? – Coughlin

+0

@PauldeLange ¿qué es _firstForKeyPath, es una API privada? – onmyway133

+0

no se utiliza API privada –

14

@PauldeLange - Su respuesta y enlaces fueron útiles.
La siguiente versión más simple funciona también (al menos como de Xcode 6)

id name = [work valueForKeyPath: @"[email protected]”]; 

En lo anterior 'firstObject' se refiere al método predefinido en NSArray. Si se necesita el segundo objeto, se puede definir lo siguiente:

@implementation NSArray (CustomKVOOperators) 

- (id) secondObject { 
    return [self count] >=2 ? self[1] : nil; 
} 
@end 

y uso:

id name = [work valueForKeyPath: @"[email protected]”]; 
+0

¡Buen descubrimiento y buena actualización! Esta es una forma mucho mejor de hacerlo ahora. –

+2

Me aparece "esta clase no implementa la primera operación de Objeto" – Injectios

+0

@Injectios Ya puede haber resuelto esto. En su uso, es probable que el objeto de datos (trabajo) en el que se está operando no sea un NSArray. – Parmesh

Cuestiones relacionadas