2009-08-19 10 views
26

Mam dwa modele Departament i pracownik. Departamenty mają wiele relacji (pracowników) z pracownikami. Pracownik ma pole firstName. Jak mogę uzyskać listę pracowników posortowaną według firstName, uzyskując dostęp do departmet.workers? Czy istnieje sposób dodawania deskryptorów sortowania do relacji to-wiele?Sortowanie w wielu relacjach Ustaw w podstawowych danych

+1

Jego stary nici .. Ale to działało i pomogła mi wielki czas! Book-zaznaczanie tego wątku Dzięki wszystkim .. !! – Shailesh

Odpowiedz

7

Relacje dla wielu w danych podstawowych są modelowane jako zestawy nieuporządkowane. Możesz jednak utworzyć pobraną właściwość w encji Wydziału, która zawiera deskryptor sortowania lub możesz sortować ustawienia w pamięci w aplikacji (NSArrayController zrobi to za Ciebie, ustawiając jego właściwość sortDescriptors).

+2

Głosowałbym za pobraną nieruchomością, ponieważ wydaje się ona "najbardziej naturalna" w danych podstawowych. –

+1

@ BarryWark Zgadzam się z Karstenem, ale myślę, że byłoby lepiej, gdybyś zawarł kilka szczegółów na temat tworzenia deskryptora.Po odrobinie wyszukiwania w Google wciąż nie znalazłem sposobu, aby utworzyć deskryptor "sortowania" w pobieranej właściwości, a tylko jak dopasować zapytania typu. – csga5000

+0

Proszę podać przykład: – MobileMon

2

Musisz zdefiniować własną metodę, taką jak sortedWorkers. Coś takiego:

- (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

kod wycinek Huntera prawie pracował dla mnie, z wyjątkiem od „pracowników” jest NSSet miałem załadować go do NSMutableArray pierwszy:

- (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

Minor poprawa w stosunku Adrian Hosey użytkownika Kod:

Zamiast ręcznie iteracji po wszystkich pracowników można też po prostu zrobić:

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

    return [self.workers sortedArrayUsingDescriptors:sortDescriptors]; 
} 

Prawdopodobnie robi to dokładnie to samo, co twoja iteracja wewnętrznie, ale może w jakiś sposób sprawili, że jest bardziej wydajna. To na pewno mniej pisania ...

Uwaga: powyższe działa tylko na iOS 4.0+ i OSX 10.6+. W starszych wersjach trzeba wymienić ostatnią linię z:

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

Uhm, sortowanie to O (n * log (n)), iteracja to O (n). Chociaż jest to mniej kodu, to z pewnością wolniej. –

+1

Podczas gdy prawda, różnica między fragmentami kodu nie jest taka, że ​​jeden iteruje i jeden sortuje. Obie używają metody sortowania, po prostu Adrian używa metody [allObjects], aby przekonwertować ją do tablicy, zamiast ręcznie ją budować, wykonując iterację po zestawie –

+4

od wersji OS X 10.6 bez ręcznej iteracji ani '[allObjects] 'są niezbędne, ponieważ NSSet sam implementuje' sortedArrayUsingDescriptors: ', oszczędzając zbędne tworzenie tymczasowego NSArray. – Regexident

1

zauważam, że jest to dość stary, ale ludzie nadal będą się po niej (ja) po

Adrian Schönig był dobry. Uważam, że jest to przydatne dla podstaw, ale musisz robić to za każdym razem, gdy chcesz uzyskać dostęp do zbioru pracowników. To bardzo nieefektywne!

Zamiast tego lepszym rozwiązaniem jest sortowanie za każdym razem, gdy wstawia się nowy obiekt, a następnie zapisanie go jako Set w CoreData. Oznacza to, że za każdym razem, gdy wywołasz CoreData, pracownicy zostaną zamówieni.

Zrobiłem to dla mojego systemu przy użyciu kategorii dla NSManagedObject (Worker + Methods.h). Tu mam metodę startowy dla nowego pracownika

// 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]]]; 
} 

Oczywiście jest to nieefektywne, gdy dodasz dużo pracowników, ale można po prostu przenieść [orderWorkers towarowe]; stanie się po dodaniu wszystkich pracowników.

7

Minor poprawa w stosunku do roztworu Adrian Schönig za:

Teraz trzeba rzucić self.workers do 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]; 
} 
Powiązane problemy