Generics und Listenstrukturen

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Generics und Listenstrukturen

    Hallo,
    ich möchte gerne ein Programm um eine Funktion erweitern.
    Und zwar um eine Suchfunktion mit der Methode FindIndex() der Klasse List.
    Im Formular habe ich drei Radiobuttons hinzugefügt (kleiner, gleich oder größer).
    Wenn der Anwender die Option kleiner markiert, soll nach dem Starten der Suche
    der erste Wert in der Liste markiert werden, der kleiner ist als das Suchkriterium.
    Bei der Option gleich soll der erste Wert markiert werden, der mit dem Suchkriterium
    übereinstimmt, und bei der Option größer der erste Wert, der größer ist als das Suchkriterium.
    Falls die Suche kein Ergebnis liefert, soll eine entsprechende Meldung ausgegeben werden.
    Ich frage mich wie ich das am besten programmieren soll. Eventuell mit einer extra Methode
    für die Predicate Delegaten?
    Ich wäre sehr dankbar für eure Hilfe.
    Hier ist der Quellcode und ein Foto von dem Formular.

    VB.NET-Quellcode

    1. Public Class Form1
    2. 'das Feld für die Liste
    3. Private liste As List(Of Integer)
    4. Private zufall As Random
    5. 'eine eigene Methode zum Aktualisieren der Liste
    6. Private Sub listeAktualisieren()
    7. 'alle Einträge löschen
    8. listBox1.Items.Clear()
    9. 'und die Liste neu aufbauen
    10. For schleife As Integer = 0 To liste.Count - 1
    11. listBox1.Items.Add(liste(schleife))
    12. Next
    13. 'den maximalen Wert für das einzelne Einfügen setzen
    14. numericUpDownNeuPosition.Maximum = liste.Count + 1
    15. 'wenn die Liste leer ist, werden die Schaltflächen
    16. 'zum Löschen, Suchen und Sortieren deaktiviert
    17. If liste.Count = 0 Then
    18. buttonSuchen.Enabled = False
    19. buttonSortieren.Enabled = False
    20. buttonLoeschen.Enabled = False
    21. buttonAlleLoeschen.Enabled = False
    22. 'den maximalen Wert zum Löschen setzen
    23. numericUpDownLoeschen.Maximum = 1
    24. Else
    25. buttonSuchen.Enabled = True
    26. buttonSortieren.Enabled = True
    27. buttonLoeschen.Enabled = True
    28. buttonAlleLoeschen.Enabled = True
    29. 'den maximalen Wert zum Löschen setzen
    30. numericUpDownLoeschen.Maximum = liste.Count
    31. End If
    32. End Sub
    33. 'der Konstruktor
    34. Public Sub New()
    35. InitializeComponent()
    36. 'eine neue generische Liste erzeugen
    37. liste = New List(Of Integer)()
    38. 'für die Zufallszahlen
    39. zufall = New Random()
    40. 'die Liste direkt nach dem Start über die eigene Methode aktualisieren
    41. listeAktualisieren()
    42. End Sub
    43. Private Sub buttonNeuAnzahl_Click(sender As Object, e As EventArgs) Handles buttonNeuAnzahl.Click
    44. 'die neuen Elemente in die Liste stellen
    45. For schleife As Integer = 0 To CInt(numericUpDownNeuAnzahl.Value) - 1
    46. liste.Add(zufall.Next(1000))
    47. Next
    48. 'die Liste aktualisieren
    49. listeAktualisieren()
    50. End Sub
    51. Private Sub buttonNeuPosition_Click( sender As Object, e As EventArgs) Handles buttonNeuPosition.Click
    52. 'einen neuen Eintrag an der gewünschten Position einfügen
    53. liste.Insert(CInt(numericUpDownNeuPosition.Value) - 1, zufall.Next(1000))
    54. 'die Liste aktualisieren
    55. listeAktualisieren()
    56. End Sub
    57. Private Sub buttonLoeschen_Click(sender As Object,,e As EventArgs) Handles buttonLoeschen.Click
    58. 'den Eintrag an der gewünschte Position löschen
    59. liste.RemoveAt(CInt(numericUpDownLoeschen.Value) - 1)
    60. 'die Liste aktualisieren
    61. listeAktualisieren()
    62. End Sub
    63. Private Sub buttonSuchen_Click(sender As Object, e As EventArgs) Handles buttonSuchen.Click
    64. 'steht überhaupt etwas im Suchfeld?
    65. If textBox1.Text = String.Empty Then
    66. Return
    67. End If
    68. 'für das Suchergebnis
    69. Dim pos As Integer
    70. 'die Suche durchführen mit dem Wert aus dem Textfeld
    71. pos = liste.IndexOf(CInt(textBox1.Text))
    72. 'wenn etwas gefunden wurde, in der Liste markieren
    73. If pos > -1 Then
    74. listBox1.SelectedIndex = pos
    75. Else
    76. MessageBox.Show("Der Wert befindet sich nicht in der Liste.")
    77. End If
    78. End Sub
    79. Private Sub buttonAlleLoeschen_Click(sender As Object, e As EventArgs) Handles buttonAlleLoeschen.Click
    80. 'alle Einträge in der Liste löschen
    81. liste.Clear()
    82. 'die Liste aktualisieren
    83. listeAktualisieren()
    84. End Sub
    85. Private Sub buttonSortieren_Click(sender As Object, e As EventArgs) Handles buttonSortieren.Click
    86. 'die Liste sortieren
    87. liste.Sort()
    88. 'die Liste aktualisieren
    89. listeAktualisieren()
    90. End Sub
    91. Private Sub buttonBeenden_Click(sender As Object, e As EventArgs) Handles buttonBeenden.Click
    92. 'die Anwendung beenden
    93. Close()
    94. End Sub
    95. End Class


    MfG

    Code zur Lesbarkeit verholfen ~ EaranMaleasi
    Bilder
    • Unbenannt.JPG

      35,64 kB, 505×357, 21 mal angesehen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „EaranMaleasi“ ()

    Am besten macht man sowas mit einem typisierten Dataset und Databinding.
    Aber wäre eine Menge zu lernen - und grad mit einer dummen Liste von Zahlen geht das nicht, weil ein Dataset besteht aus Datensätzen - das sind Klassen, die jeweils mehrere Properties haben, und wenn man sb. eine gefilterte oder sortierte Ansicht will, muss man die Property mit angeben, nach der gefiltert/sortiert sein soll.
    Aber ist das realistischere Szenario, weil ich glaub kaum dass man mit einem Proggi was anfangen kann, was nur eine Zahlen-Liste sortieren/filtern/durchsuchen kann.

    Bei Interesse frag nochma.l
    Da gebe ich dir völlig recht. Mit einer Datenbank wäre es viel einfacher. Leider ist es eine Aufgabe in meinem Fernstudium,
    die leider so gelöst werden muss.
    Den Sinn dahinter erkenn ich auch nicht. Ich zerbreche mir jetzt schon seit Tagen den Kopf darüber aber komme nicht
    auf die Lösung. Ich hab zwar einen Ansatz aber der funktioniert nicht. Vielleicht hast du eine Idee?
    Danke im Voraus
    Hi, anhand dieser Aussage nehme ich mal an, dass du FindIndex benutzen musst:

    Vogel87 schrieb:

    [...] mit der Methode FindIndex() [...]


    In diesem Fall geht dein Gedankengang auf jeden Fall schomal in die richtige Richtung:

    Vogel87 schrieb:

    Eventuell mit einer extra Methode
    für die Predicate Delegaten?


    FindIndex gibt dir den Index des ersten Elements zurück, das eine gewisse Bedingung (dein Predicate) erfüllt. Falls keines der Elemente die Bedingung erfüllt, bekommst du -1 zurück.
    Wenn du jetzt als Predicate deine jeweils nötige Bedingung einsetzt, bekommst du auch den gesuchten Index. (Hinweis: Insgesamt hast du 3 verschiedene Bedingungen wegen den 3 möglichen Suchrichtungen, also wirst du voraussichtlich auch 3 Predicates brauchen).
    Hier mal ein kleiner Denkanstoß, der dich in die richtige Richtung führen könnte:

    Visual Basic-Quellcode

    1. Dim index As Integer = liste.FindIndex(Function(zahl) zahl = 13)
    2. If index = -1 Then
    3. Console.WriteLine("Keine Zahl erfüllt die Bedingung.")
    4. Else
    5. Console.WriteLine($"Die Zahl an Index {index} (Wert = {liste(index)}) erfüllt die Bedingung.")
    6. End If

    Vogel87 schrieb:

    Da gebe ich dir völlig recht. Mit einer Datenbank wäre es viel einfacher.
    Achtung! (da seh ich immer rot)
    Ein typisiertes Dataset ist keine Datenbank.
    Und mit einer Datenbank wäre es mitnichten einfacher, das wäre einfach mit Kanonen auf Spatzen geschossen.

    Aber gut - wenn du an einem Fernstudium leidest, kann man natürlich nicht über die Sinnhaftigkeit der Aufgaben debattieren.

    Wirklich eine Idee hab ich nicht. > 100 Zeilen Code sind mir zuviel, um da so vom Angucken her durchzusteigen, und du hast auch keinen Hinweis gegeben, was genau da nicht funzt.
    (oder ich habs überlesen - ich muss zugeben, bin ein echt schlampiger leser)
    Ich sehe da was von liste.IndexOf(), liste.Sort(), und ListeAktualisieren() - das sieht mir auf dem ersten Blick garnet so verkehrt aus.
    Möglicherweise ein Teufel im Detail - also ich seh ihn grad nicht.

    Du kannst dein Werk aber auch zippen und als DateiAnhang anhängen. Aber bitte ohne den bin-Ordner.Binaries verteilen sehen wir nicht so gerne im Forum.
    Anleitung:

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Hallo,
    also der Code den ich geschickt hatte Funktionniert, so weit alles ok.
    Leider hat mir der Denkanstoss nicht geholfen.
    Ich dachte ich müsste es umgefähr so programmieren aber bekomme viele Fehlermeldungen.

    VB.NET-Quellcode

    1. Private Shared Function findeklein(Zahl As Integer) As Boolean
    2. If Zahl < Sukleiner Then
    3. listBox1.SelectedIndex = pos
    4. Else MessageBox.Show("Der erste Wert aus der Liste ist nicht kleiner als das Suchergebnis")
    5. End If
    6. End Function
    7. Private Shared Function findegleich(Zahl As Integer) As Boolean
    8. If Zahl = Sugleich Then
    9. listBox1.SelectedIndex = pos
    10. Else MessageBox.Show("Der erste Wert aus der Liste ist nicht gleich dem Suchergebnis")
    11. End If
    12. End Function
    13. Private Shared Function findegroesser(Zahl As Integer) As Boolean
    14. If Zahl > Sugroesser Then
    15. listBox1.SelectedIndex = pos
    16. Else MessageBox.Show("Der erste Wert aus der Liste ist nicht größer als das Suchergebnis")
    17. End If
    18. End Function
    19. 'Für die delegaten
    20. Public Shared Sub main()
    21. Dim Sukleiner As New Predicate(Of Integer)(AdressOf findeklein)
    22. Dim Sugleich As New Predicate(Of Integer)(AdressOf findegleich)
    23. Dim Sugroesser As New Predicate(Of Integer)(AdressOf findegroesser)
    24. End Sub


    Wie gesagt ich komme einfach nicht drauf.
    Ich schicke euch mal als Anhang mein Werk. Der Abschnitt der nicht Funktionniert ist ausgeklammert.

    MfG
    Dateien
    Geht bestimmt auch schöner, aber in der buttonSuchen_Click-Prozedur den If pos > -1 Then-Block weg und stattdessen

    VB.NET-Quellcode

    1. Dim FittingListIndex = -1
    2. If rbkleiner.Checked Then FittingListIndex = liste.FindIndex(Function(x) x < Integer.Parse(textBox1.Text))
    3. If rbgroesser.Checked Then FittingListIndex = liste.FindIndex(Function(x) x > Integer.Parse(textBox1.Text))
    4. If rbgleich.Checked Then FittingListIndex = liste.FindIndex(Function(x) x = Integer.Parse(textBox1.Text))
    5. If FittingListIndex = -1 Then MessageBox.Show("keinen passenden Eintrag gefunden") : Return
    6. listBox1.SelectedIndex = FittingListIndex
    Allerdings gefällt mir diese Mischung aus liste-prüfen und ListBox-Manipulieren nicht sonderlich. Das kann früher oder später daneben gehen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.