0

Ich versuche, ein NSArray mit einer benutzerdefinierten alphabetischen Reihenfolge zu sortieren. Der Deal ist, dass ich ein Array mit Strings habe, die Zustände von Objekten enthalten.NSSortDescriptor benutzerdefinierte alphanumerische Reihenfolge

Die verfügbaren Zustände sind entered, process, ready, done.

Wenn ich sie jetzt normal sortiere (in alphabetischer Reihenfolge), wäre die Reihenfolge falsch (erledigt, eingegeben, verarbeitet, fertig).

Ich habe versucht, den folgenden Code es den richtigen Weg, um zu bestellen:

NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"state" ascending:YES comparator:^(id obj1, id obj2) { 
    if ([obj1 isEqualToString:@"entered"] && [obj2 isEqualToString:@"process"]) { 
     return (NSComparisonResult) NSOrderedAscending; 
    } 
    else if ([obj1 isEqualToString:@"process"] && [obj2 isEqualToString:@"entered"]) { 
     return (NSComparisonResult) NSOrderedDescending; 
    } 
    else if ([obj1 isEqualToString:@"process"] && [obj2 isEqualToString:@"ready"]) { 
     return (NSComparisonResult) NSOrderedAscending; 
    } 
    else if ([obj1 isEqualToString:@"ready"] && [obj2 isEqualToString:@"process"]) { 
     return (NSComparisonResult) NSOrderedDescending; 
    } 
    else if ([obj1 isEqualToString:@"ready"] && [obj2 isEqualToString:@"done"]) { 
     return (NSComparisonResult) NSOrderedAscending; 
    } 
    else if ([obj1 isEqualToString:@"done"] && [obj2 isEqualToString:@"ready"]) { 
     return (NSComparisonResult) NSOrderedDescending; 
    } 
    else { 
     return (NSComparisonResult) NSOrderedSame; 
    } 
}]; 

Ich habe auch versucht, nur die ersten Buchstaben der Worte verwenden, aber es hat nicht zu arbeiten.

Wenn ich diesen Komparator verwende, ist es einfach nicht zu bestellen bzw.. Das Array behält die "alte" Reihenfolge bei.

Was mache ich falsch? Habe ich die Komparatoren nicht richtig verstanden?

Vielen Dank für Hilfe, Mit freundlichen Grüßen, Julian

Antwort

0

Ich muss antworten, weil ich eine Menge Code hier habe. Ich habe jetzt das Ding am Laufen. Aber es gibt eine lustig bug :)

NSString *str1 = (NSString *)obj1; 
NSString *str2 = (NSString *)obj2; 

if ([str1 isEqualToString:@"entered"] && [str2 isEqualToString:@"progress"]) { 
    return (NSComparisonResult) NSOrderedAscending; 
} 
else if ([str1 isEqualToString:@"entered"] && [str2 isEqualToString:@"ready"]) { 
    return (NSComparisonResult) NSOrderedAscending; 
} 
else if ([str1 isEqualToString:@"entered"] && [str2 isEqualToString:@"done"]) { 
    return (NSComparisonResult) NSOrderedAscending; 
} 
else if ([str1 isEqualToString:@"progress"] && [str2 isEqualToString:@"entered"]) { 
    return (NSComparisonResult) NSOrderedDescending; 
} 
else if ([str1 isEqualToString:@"progress"] && [str2 isEqualToString:@"ready"]) { 
    return (NSComparisonResult) NSOrderedAscending; 
} 
else if ([str1 isEqualToString:@"progress"] && [str2 isEqualToString:@"done"]) { 
    return (NSComparisonResult) NSOrderedAscending; 
} 
else if ([str1 isEqualToString:@"ready"] && [str2 isEqualToString:@"entered"]) { 
    return (NSComparisonResult) NSOrderedDescending; 
} 
else if ([str1 isEqualToString:@"ready"] && [str2 isEqualToString:@"progress"]) { 
    return (NSComparisonResult) NSOrderedDescending; 
} 
else if ([str1 isEqualToString:@"ready"] && [str2 isEqualToString:@"done"]) { 
    return (NSComparisonResult) NSOrderedDescending; 
} 
else if ([str1 isEqualToString:@"done"] && [str2 isEqualToString:@"entered"]) { 
    return (NSComparisonResult) NSOrderedDescending; 
} 
else if ([str1 isEqualToString:@"done"] && [str2 isEqualToString:@"progress"]) { 
    return (NSComparisonResult) NSOrderedDescending; 
} 
else if ([str1 isEqualToString:@"done"] && [str2 isEqualToString:@"ready"]) { 
    return (NSComparisonResult) NSOrderedDescending; 
} 
else { 
    return (NSComparisonResult) NSOrderedSame; 
} 

Jetzt ist der Fehler: Wenn ich die Reihenfolge Richtungswechsel (ascending:YES/NO), ist die Richtung stimmt jedes zweite Mal, ich befehle ascending:YES (eingegeben, Fortschritt, fertig, fertig). Ansonsten ist es ein bisschen falsch: eingegeben, fertig, fertig, fertig.

Kann sich jemand vorstellen warum oder hat eine Lösung dafür? Es ist kein ernsthafter Fehler, aber ich möchte es beheben.

Danke, Mundi, aber ich denke, ich benutze meinen fuzzy Stil weiter. Ich bin ziemlich neu in Cocoa/Objective C und jetzt macht es mehr Sinn für mich. Trotzdem danke für deine Mühe !!

0

Ich denke, dass Ihr Schema mit Saiten für nicht geeignet ist, was Sie zu tun versuchen. Zum Aufzeichnen von Zuständen ist es viel besser, ein anderes Datenmodell zu verwenden und sich um die entsprechenden Zeichenfolgen in der Ansicht zu kümmern.

Eine gemeinsame Implementierung beinhaltet eine enum, die automatisch erhöht, wenn Sie es wie folgt definieren:

typedef enum { 
    entered = 0, 
    processed, 
    ready, 
    done 
} State; 

jetzt Sortierung trivial wird.

Ihre state sollte vom Typ State sein, was praktisch eine ganze Zahl ist. Sie müssen es in einem NSNumber umschließen, wenn Sie NSDictionary oder NSArray verwenden möchten, aber es ist sicherlich besser lesbar, wenn Sie ein benutzerdefiniertes Objekt mit einem @property des Typs State erstellen.

+0

Hey Mundi! Toller Ansatz, danke! Aber jetzt: Wie könnte ich den NSString (mit den Zustandsnamen) in ein Objekt vom Typ _state_ konvertieren? Ich kann die Darstellung nicht von der Datenbank aus ändern, da meine App "nur" ein iOS-Wrapper für eine webbasierte Anwendung ist. ** Danke ** aber! –

+0

So wie Sie es mit anderen JSON- oder XML-Feldern tun würden. Ordnen Sie sie nacheinander den Eigenschaften Ihres benutzerdefinierten Objekts zu. In diesem Fall vielleicht nur mit einer Folge von if-Anweisungen. – Mundi

Verwandte Themen