C # Wie sortiere ich eine Liste, ohne IComparable manuell zu implementieren?

7

Ich habe ein ziemlich komplexes Szenario und muss sicherstellen, dass die Elemente in einer Liste sortiert sind.

Zunächst basieren die Elemente in der Liste auf einer Struktur, die eine Unterstruktur enthält.

Zum Beispiel:

%Vor%

Jetzt habe ich eine Liste bestehend aus topLevelItems zum Beispiel:

%Vor%

Ich brauche eine Möglichkeit, nach der DeliveryTime ASC zu sortieren. Was zur Komplexität beiträgt, ist, dass das DeliveryTime-Feld eine Zeichenfolge ist. Da diese Strukturen Teil einer wiederverwendbaren API sind, kann ich dieses Feld nicht zu einer DateTime ändern, noch kann ich IComparable in der topLevelItem-Klasse implementieren.

Irgendwelche Ideen wie das gemacht werden kann?

Danke

    
JL. 05.05.2010, 13:47
quelle

6 Antworten

6

Es klingt, als müssten Sie eine kanonische Datums-Sortierung erhalten, obwohl Ihr Datum als String dargestellt wird, ja? Nun, Sie können den OrderBy -Operator von LINQ verwenden, aber Sie müssen den string in ein Datum, um korrekte Ergebnisse zu erzielen:

%Vor%

Aktualisierung:

Ich habe das zur Vollständigkeit hinzugefügt - ein echtes Beispiel dafür, wie ich ParseExact mit Invariant culture verwende:

%Vor%

Sie können immer eine separate IComparer-Klasse implementieren, es macht keinen Spaß, aber es funktioniert gut:

%Vor%

Beachten Sie, dass die meisten Sort() -Methoden im .NET-Framework eine IComparer oder IComparer<T> akzeptieren, wodurch Sie die Vergleichssemantik für jeden Typ neu definieren können. Normalerweise verwenden Sie einfach Comparer<T>.Default - oder verwenden Sie eine Überladung, die dies im Wesentlichen für Sie bereitstellt.

    
LBushkin 05.05.2010, 13:52
quelle
7

Erstellen Sie einen neuen Typ, der IComparer implementiert, und verwenden Sie eine Instanz, um die Objekte zu vergleichen .

%Vor%

Sie können dann Sort () wie folgt aufrufen:

%Vor%     
Justin Niessner 05.05.2010 13:49
quelle
4

LINQ verwenden:

%Vor%     
driis 05.05.2010 13:49
quelle
4

Wenn Sie eine In-Place-Sortierung durchführen möchten, können Sie die Sort Überladung, die ein Comparison<T> Argument und eine anonyme Funktion / Lambda:

%Vor%

Wenn Sie lieber eine neue sortierte Sequenz erstellen als eine direkte Sortierung, dann ist LINQs OrderBy wahrscheinlich der richtige Weg, wie andere bereits erwähnt haben.

    
LukeH 05.05.2010 14:11
quelle
2

Nachdem ich dieses Problem hatte, habe ich einmal einen LambdaComparer implementiert, der den Vergleich basierend auf einem beliebigen Lambda-Ausdruck durchgeführt hat. Nicht genauer Code, aber etwas in dieser Richtung:

%Vor%

Ein großer Vorteil ist, dass Sie einen schönen, wiederverwendbaren Code bekommen.

    
Stephan 05.05.2010 14:10
quelle
1

Um die items -Liste selbst zu sortieren:

%Vor%

Dieser Ansatz hat den Vorteil:

  1. Sortieren der Liste an Ort und Stelle (das heißt, wenn Sie wollen die Liste direkt sortiert)
  2. Sortieren nach tatsächlichen DateTime Werten anstelle von Strings, ABER ...
  3. Keine Ausnahme, wenn eine Zeichenfolge keine gültige DateTime darstellt (im Grunde werden alle ungültigen Zeichenfolgen auf einer Seite der Liste angezeigt)
Dan Tao 05.05.2010 14:45
quelle

Tags und Links