2011-05-21 15 views
13

Próbuję sortować NSArray, który jest wypełniony niestandardowymi obiektami. Każdy obiekt ma właściwość startDateTime, która jest typu NSDate.Sortowanie NSArray obiektów niestandardowych według ich właściwości NSDate

Następujący kod powoduje, że tablica, sortedEventArray, jest wypełniona, ale nie jest posortowana. Czy podchodzę do tego zupełnie niewłaściwie, czy też brakuje mi czegoś małego?

NSSortDescriptor *dateDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"startDateTime" 
                   ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor]; 
NSArray *sortedEventArray = [nodeEventArray sortedArrayUsingDescriptors:sortDescriptors]; 
+0

kod wydaje się całkiem dobrze. Jesteś pewien, że masz właściwy klucz? –

+0

@Firoze: Tak, potrójnie sprawdziłem nazwę. "startDateTime" to nazwa właściwości NSDate w mojej klasie niestandardowej. – markdorison

+2

Problem okazał się być gdzie indziej w moim kodzie, więc zastanawiałem się nad zamknięciem pytania, ale ze względu na pomocny charakter poniższych odpowiedzi, zamierzam zostawić to tutaj, ponieważ uważam, że inni mogą uznać to za użyteczne. – markdorison

Odpowiedz

25

Czy jesteś pewien, że zmienne instancji startDateTime zdarzeń węzła są zerowe?

Jeśli nie masz, możesz dodać (na zamówienie) -description metodę do swoich obiektów zdarzeń węzeł, który robi coś takiego:

- (NSString *)description { 
    return [NSString stringWithFormat:@"%@ - %@", 
        [super description], startDateTime]]; 
} 

Następnie w kodzie sortowania logowaniu tablicę przed i po:

NSLog(@"nodeEventArray == %@", nodeEventArray); 
NSSortDescriptor *dateDescriptor = [NSSortDescriptor 
            sortDescriptorWithKey:@"startDateTime" 
               ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor]; 
NSArray *sortedEventArray = [nodeEventArray 
     sortedArrayUsingDescriptors:sortDescriptors]; 
NSLog(@"sortedEventArray == %@", sortedEventArray); 

Jeśli startDateTime „s są nil, to przed i po tablice będą miały taką samą kolejność (od operacja sortowania będzie równoznaczny z wysłaniem wszystkie wiadomości -compare: do nil, który zasadniczo nic nie robi).

11

Czy próbowałeś, określając komparator NSDate?

Np

NSSortDescriptor *dateDescriptor = [NSSortDescriptor 
    sortDescriptorWithKey:@"startDateTime" 
    ascending:YES 
    selector:@selector(compare:)]; 

ta powinna wymusić użycie poprawnej komparatora klasy NSDate.

+1

Ta zmiana nie miała wpływu na moje wyniki. – markdorison

11

Ok, wiem, że to trochę późno, ale jest to w jaki sposób to zrobić:

NSArray *sortedEventArray = [events sortedArrayUsingComparator:^NSComparisonResult(Event *event1, Event *event2) { 
    return [event1.startDateTime compare:event2.startDateTime]; 
}]; 

Oczywiście zastąpić zdarzenie z klasy niestandardowego obiektu. Zaletą tego podejścia jest to, że jesteś chroniony przed przyszłym refaktoryzowaniem. Jeśli miałbyś zrekompensować i zmienić nazwę właściwości startDateTime na coś innego, Xcode prawdopodobnie nie zmieniłby napisu, który przechodzisz do deskryptora sortowania. Nagle twój kod sortowania złamał/nic nie zrobił.

+0

Zgadzam się z tobą. FYI chociaż, mała literówka. To: "sortedArrayUsingComparator:" –

+0

Działa jak czar, dzięki. –

+0

@PaulEvans użyłem - [NSMutableArray sortUsingComparator:], jak zauważyłem w moim komentarzu. Jednak mogę go zmienić, aby zwrócić nową posortowaną tablicę zgodnie z przykładem OP. Dzięki :) – slottermoser

0

Można to osiągnąć w ten sposób,

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:FALSE]; 

[self.Array sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
0

można osiągnąć w ten sposób,

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"anyDateField" ascending:YES]; 

NSMutableArray *arr = [[array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]mutableCopy]; 
Powiązane problemy