2009-08-19 37 views
26

Tengo dos modelos Departamento y Trabajador. Los departamentos tienen muchas relaciones (trabajadores) con los trabajadores. El trabajador tiene el campo firstName. ¿Cómo puedo obtener una lista de trabajadores clasificada por firstName accediendo a departmet.workers? ¿Hay alguna manera de agregar descriptores de ordenamiento en la relación de muchos?Ordenando aMucha relación Establecer en datos básicos

+1

Es un hilo de edad .. Pero funcionó y me ayudó a lo grande! Marcado de libro este hilo ¡¡Gracias a todos !! – Shailesh

Respuesta

7

Para muchas relaciones en Core Data se modelan como conjuntos desordenados. Sin embargo, puede crear una propiedad captada en la entidad del Departamento que incluye un descriptor de clasificación o puede ordenar el conjunto en memoria dentro de su aplicación (NSArrayController hará esto por usted configurando su propiedad sortDescriptors).

+2

Votaría por una propiedad recuperada ya que parece ser la "forma más natural" en Core Data. –

+1

@BarryWark Estoy de acuerdo con Karsten, pero creo que sería mejor si incluyese algunos detalles sobre cómo crear el descriptor.Después de buscar un poco en Google, todavía no he encontrado cómo hacer un descriptor de "clasificación" en una propiedad recuperada, solo cómo hacer coincidir las consultas de tipo. – csga5000

+0

Proporcione el ejemplo – MobileMon

2

Debe definir su propio método, como sortedWorkers. Algo como esto:

- (NSArray *)sortedWorkers { 
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease]; 
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease]; 

    return [self.workers sortedArrayUsingDescriptors:sortDescriptors]; 
} 
3

sección de código de Hunter casi funcionó para mí, excepto que como "trabajadores" es una NSSet, que tenía que cargarlo en un NSMutableArray primera:

- (NSArray *)sortedWorkers { 
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease]; 
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease]; 

    NSMutableArray *sortThese = [NSMutableArray arrayWithCapacity:[self.workers count]]; 
    for (id worker in self.workers) { 
     [sortThese addObject:worker]; 
    } 

    return [sortThese sortedArrayUsingDescriptors:sortDescriptors]; 
} 
31

pequeña mejora respecto Adrian Hosey de código:

En lugar de iterar manualmente sobre todos los trabajadores también se puede simplemente hacer:

-(NSArray *)sortedWorkers { 
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease]; 
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease]; 

    return [self.workers sortedArrayUsingDescriptors:sortDescriptors]; 
} 

Probablemente hace exactamente lo mismo que su iteración internamente, pero tal vez lo hicieron más eficiente de alguna manera. Ciertamente es menos tipeado ...

Nota: lo anterior solo funciona en iOS 4.0+ y OSX 10.6+. En las versiones anteriores es necesario sustituir la última línea con:

return [[self.workers allObjects] sortedArrayUsingDescriptors:sortDescriptors]; 
+3

Uhm, la ordenación es O (n * log (n)), iterando es O (n). Si bien esto es menos código, es ciertamente más lento. –

+1

Si bien es cierto, la diferencia entre los fragmentos de código no es una iteración y un orden. Ambos usan el método de clasificación, es solo que Adrian está usando el método [allObjects] para convertir a una matriz en lugar de construir uno manualmente iterando sobre el conjunto –

+4

A partir de OS X 10.6 ni iteración manual, ni '[allObjects] 'son necesarios ya que NSSet implementa' sortedArrayUsingDescriptors: ', ahorrando la creación superflua de un NSArray temporal. – Regexident

1

noto que esto es bastante antiguo, pero la gente todavía se encontrará con él (lo hice) después de

Adrian Schönig era bueno. Lo encontré útil para los conceptos básicos, pero debe hacer este tipo cada vez que desee acceder al Conjunto de trabajadores. Esto es muy ineficiente!

En cambio, lo mejor es hacer el orden cada vez que inserta un objeto nuevo y luego guardarlo como el Conjunto en CoreData. Esto significa que cada vez que llame a CoreData se ordenará a los trabajadores.

Hice esto para mi sistema usando una Categoría para NSManagedObject (Worker + Methods.h). Aquí tengo el método init para un nuevo trabajador

// Worker+Methods.m 
+(Worker *)newWorkerWithFirstname:(NSString *)firstName department:(Department *)department managedContext:(NSManagedObjectContext *)context { 
    Worker *w = [NSEntityDescription insertNewObjectForEntityForName:@"Worker" inManagedObjectContext:context]; 
    w.firstName = firstName; 
    w.department = department; 

    [department orderWorkers]; 
    return s; 
} 


//Department+Methods.m 
-(void)orderServices { 
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease]; 
    self.workers = [[NSSet alloc] initWithArray:[self.workers sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortNameDescriptor]]]; 
} 

Obviamente, esto es ineficiente cuando se agrega una gran cantidad de trabajadores, pero sólo se puede mover [orderWorkers departamento]; que suceda después de que se agreguen todos los trabajadores.

7

pequeña mejora respecto solución de Adrian Schönig:

Por ahora es necesario convertir a self.workers NSSet *

-(NSArray *)sortedWorkers { 
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease]; 
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease]; 

    return [(NSSet*)self.workers sortedArrayUsingDescriptors:sortDescriptors]; 
} 
Cuestiones relacionadas