List(of Structure) sortieren ...

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von EaranMaleasi.

    List(of Structure) sortieren ...

    Hi,

    ich habe zwei File Listen. Die sind wie folgt definiert und befüllt:

    VB.NET-Quellcode

    1. Dim List1 As New List(Of myListEntry)
    2. Dim List2 As New List(Of myListEntry)
    3. Dim myEntry As New myListEntry


    VB.NET-Quellcode

    1. Private Structure myListEntry
    2. Dim fileName As String
    3. Dim fileLastChanged As DateTime
    4. Dim fileSize As Integer
    5. Dim fileIndex As Integer
    6. End Structure


    Ich will die beiden Listen mit einem "Match/Merge" abgleichen. Wie man das programmatisch handhabt, weiß ich. Aber die beiden Listen müssen dazu unbedingt aufsteigend nach dem "fileName" sortiert sein. Und daran hapert es jetzt.

    Naiv wie ich nun mal bin, hab ich das folgendermaßen versucht:

    VB.NET-Quellcode

    1. List1.Sort()
    2. List2.Sort()


    Das war halt zu optimistisch von mir. Die Syntax ist zwar ok, aber zur Laufzeit setzt es eine "operating exception".

    Wie macht man das denn jetzt richtig ? Muss ich da einen eigenen Sortierer schreiben ? Ich denke, so eine Standard Aufgabe sollte doch einfacher zu lösen sein.

    Na, ihr wisst das sicher viel besser als ich. Es wäre nett, wenn ihr mir wieder (ein ums andere Mal) nachsichtig helfen könntet! :)

    LG
    Peter
    Hallo

    Google spuckt beim ersten suchergebniss gleich das korrekte Beispiel aus denke ich.

    z.b. so:

    VB.NET-Quellcode

    1. List1 = List1.OrderBy(Function(s) s.fileName)

    oder

    VB.NET-Quellcode

    1. List1 = From f in List1 Order By c.filename select c


    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Ich hab das einfach mal ausprobiert:

    VB.NET-Quellcode

    1. List1 = List1.OrderBy(Function(s) s.fileName)


    Fehler BC30512 "Option Strict On" lässt keine impliziten Konvertierungen von "IOrderedEnumerable(Of Form1.myListEntry)" in "List(Of Form1.myListEntry)" zu.

    VB.NET-Quellcode

    1. List1 = From f In List1 Order By c.filename Select c


    BC36610 Der Name "c" ist entweder nicht deklariert oder im aktuellen Bereich ungültig.

    VB.NET-Quellcode

    1. List1 = Select c From f In List1 Order By c.filename


    Ausdruck erwartet ...

    Ansonsten sieht das ja schon ganz ordentlich aus ! :)

    LG
    Peter
    Sorry, mein Fehler. Habs nur schnell runtergetippt.

    Natürlich so: List1 = List1.OrderBy(Function(s) s.fileName).ToList

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Peter329 Falls Du mal in Verlegenheit sein solltest, bei zwei gleichen Sortierwerten nach einem weiteren Wert sortieren zu müssen, musst Du zwei Sortierungen angeben.
    Zuerst OrderBy(),
    danach ThenBy():

    VB.NET-Quellcode

    1. List1 = List1.OrderBy(Function(s) s.fileName).ThenBy(Function(s) s.fileLastChanged).ToList()
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    nikeee13 schrieb:

    solltest du auch die Sort-Funktion nutzen können.
    Da musst Du abern alles zu Fuß implementieren.
    Allerdings hat das möglicherweise eine höhere Performance als LINQ.
    ================
    Es ist deutlich performanter.
    Ich hab der Struktue zwei IComparer-Klassen gemacht, um unterschiedlich sortieren zu können.
    Die Laufzeiten (LINQ - IComparer) verhalten sich etwa wie 3 : 2 :!:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Structure Test
    3. Public Text As String
    4. Public Value As Integer
    5. Public Sub New(ByVal t As String, ByVal v As Integer)
    6. Me.Text = t
    7. Me.Value = v
    8. End Sub
    9. Public Overrides Function ToString() As String
    10. Return String.Format("{0} - {1}", Text, Value)
    11. End Function
    12. End Structure
    13. Dim List1 As New List(Of Test)
    14. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    15. 'List1.Add(New Test("a", 10))
    16. 'List1.Add(New Test("a", 9))
    17. 'List1.Add(New Test("c", 7))
    18. 'List1.Add(New Test("a", 11))
    19. 'List1.Add(New Test("a", 7))
    20. 'List1.Add(New Test("b", 8))
    21. 'List1.Add(New Test("b", 7))
    22. Dim rnd As New Random
    23. For i = 1 To 1000
    24. List1.Add(New Test(Convert.ToChar(rnd.Next(33, 127)), rnd.Next(0, 20)))
    25. Next
    26. ListBox1.DataSource = List1
    27. End Sub
    28. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    29. List1 = List1.OrderBy(Function(s) s.Text).ThenBy(Function(s) s.Value).ToList()
    30. ListBox1.DataSource = Nothing
    31. ListBox1.DataSource = List1
    32. End Sub
    33. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    34. List1 = List1.OrderBy(Function(s) s.Value).ThenBy(Function(s) s.Text).ToList()
    35. ListBox1.DataSource = Nothing
    36. ListBox1.DataSource = List1
    37. End Sub
    38. Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    39. Dim sw = Stopwatch.StartNew
    40. For i = 1 To 1000
    41. List1 = List1.OrderBy(Function(s) s.Text).ThenBy(Function(s) s.Value).ToList()
    42. List1 = List1.OrderBy(Function(s) s.Value).ThenBy(Function(s) s.Text).ToList()
    43. Next
    44. sw.Stop()
    45. ListBox2.Items.Add(sw.ElapsedMilliseconds)
    46. End Sub
    47. Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
    48. Dim sw = Stopwatch.StartNew
    49. For i = 1 To 1000
    50. List1.Sort(New Compare1)
    51. List1.Sort(New Compare2)
    52. Next
    53. sw.Stop()
    54. ListBox3.Items.Add(sw.ElapsedMilliseconds)
    55. End Sub
    56. Public Class Compare1
    57. Implements IComparer(Of Test)
    58. Public Function Compare(x As Test, y As Test) As Integer Implements IComparer(Of Test).Compare
    59. If x.Text = y.Text Then
    60. Return x.Value.CompareTo(y.Value)
    61. End If
    62. Return x.Text.CompareTo(y.Text)
    63. End Function
    64. End Class
    65. Public Class Compare2
    66. Implements IComparer(Of Test)
    67. Public Function Compare(x As Test, y As Test) As Integer Implements IComparer(Of Test).Compare
    68. If x.Value = y.Value Then
    69. Return x.Text.CompareTo(y.Text)
    70. End If
    71. Return x.Value.CompareTo(y.Value)
    72. End Function
    73. End Class
    74. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    RodFromGermany schrieb:

    Da musst Du abern alles zu Fuß implementieren.
    Ja, richtig. Es ist semantisch auch etwas anderes. Schließlich definiert man damit, welche der zwei struct-Instanzen "größer" ist. Wenn man eine Liste nach einem Attribut sortieren will, handelt es sich um einen anderen use case.
    Von meinem iPhone gesendet