2 Stimmen

Verwenden von CompareTo() zum Sortieren nach mehreren Spalten

Derzeit habe ich ein Objekt, das die IComparable-Schnittstelle implementiert (ASP.NET 3.5, VB). Wenn ich mehrere instanziierte Objekte in eine Generics-Liste einfüge, sortiere ich sie, indem ich eine einfache someList.Sort . Meine CompareTo() Funktion ist diese:

Public Function CompareTo(ByVal obj As Object) As Integer Implements 
System.IComparable.CompareTo
    'default is number of votes (opposite direction, highest first)'
    Dim sent As Sentence = CType(obj, Sentence)
    Return Not Points.CompareTo(sent.Points)
End Function

Das funktioniert gut, aber jetzt muss ich nach einer anderen Eigenschaft sortieren, der DateSubmitted-Eigenschaft, als Teilmenge der Punkte. Zum Beispiel, wenn drei Sätze Stimmen haben: 3, 1, 1, möchte ich, dass der Satz mit den meisten Stimmen an erster Stelle steht (natürlich) und von den beiden Sätzen mit einer Stimme derjenige aufgelistet wird, der am frühesten eingereicht wurde.

Ist dies mit CompareTo() möglich, oder sollte ich einfach die Datenbank erneut aufrufen und sie dort sortieren?

感謝

6voto

Joel Coehoorn Punkte 377088

Ihre CompareTo()-Funktion ist falsch. Sie müssen korrekte Ergebnisse für drei Zustände (<, = und >) zurückgeben, und Ihre Not bedeutet, dass die Funktion nur zwei von ihnen korrekt behandelt. Diese wird Probleme verursachen, wenn Sie die Funktion für eine ausreichend große Liste aufrufen.

Wie MehrdadA bereits erwähnt hat, bietet .Net 3.5 eine einfachere Möglichkeit, dies zu handhaben. Aber hier ist, wie es zu tun, wenn aus irgendeinem Grund Sie die Lambda-Ausdrücke nicht behandeln können:

Public Function CompareTo(Of Sentence)(ByVal obj As Sentence) As Integer _
  Implements System.IComparable.CompareTo(Of Sentence)

    If obj Is Nothing Return 1
    Dim result As Integer = Points.CompareTo(obj.Points) * -1
    If result = 0 Then result = DateSubmitted.CompareTo(obj.DateSubmitted)
    Return result
End Function

Beachten Sie, dass Sie nun Folgendes implementieren wollen IComparable(Of T) statt IComparable .

0 Stimmen

+1, danke... ich ging w/the linq Lösung, aber dies half mir verstehen CompareTo()

2voto

mmx Punkte 400975

Da Sie mit .NET 3.5 arbeiten, können Sie die Sortierung mit der OrderBy Erweiterungsmethode leicht:

Dim someSortedList = someList.OrderBy(Function(item) item.SomeColumn) _
                             .ThenBy(Function(item) item.SomeOtherColumn)
                             .ToList()

' OrderByDescending and ThenByDescending are also there for descending order

Ob Sie die Datenbank erneut aufrufen sollten oder nicht, hängt davon ab, wie Sie die Daten überhaupt abgerufen haben. Wenn Sie einen großen Datensatz haben und nur eine kleine Teilmenge davon aus der DB abgerufen haben, dann sollten Sie die DB lediglich bitten, eine kleine Teilmenge der Daten auf der Grundlage der neuen Sortierreihenfolge zu holen. Andernfalls, wenn Sie den gesamten Datensatz bereits im Speicher haben, sortieren Sie ihn einfach wie oben beschrieben.

0 Stimmen

Ich kann nicht bekommen someList.OrderBy in der Intellisense auftauchen... ich bin ziemlich sicher, ich bin mit 3.5 (ich bin mit VS08), aber ich denke, es ist möglich, ich bin nicht?

1 Stimmen

Haben Sie Imports System.Linq ? Stellen Sie sicher, dass ein "<add namespace="System.Linq" />" in Ihrer Web.config vorhanden ist.

0 Stimmen

Ah! ok... ich habe Linq importiert... was bedeutet "item"? ist das ein instanziertes Objekt?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X