Hashtable mit mehreren Listen als Value, wie funktionieren Min/Max/Contains-Methoden??

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    Hashtable mit mehreren Listen als Value, wie funktionieren Min/Max/Contains-Methoden??

    Hallo zusammen,

    ich habe in meinem Hashtable mehrere Listen als Values.
    Bei der Verwendung der Listen habe ich noch keine Möglichkeit gefunden, das Minimum über alle Listen aus allen Keys zu bestimmen oder einen Wert über die "ContainsValue"-Methode abzufragen.

    Momentan konnte ich mit Hilfslisten und for-Schleifen weiterhelfen, allerdings ist das jetzt nicht besonders elegant und da muss es doch eine einfachere Möglichkeit geben?!

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim TestHash As New Hashtable
    4. TestHash.Add(1,
    5. New Items With
    6. {
    7. .Zeit = New List(Of Integer) From {2, 5, 6},
    8. .Name = New List(Of String) From {"abc", "def", "ghi"}
    9. }
    10. )
    11. TestHash.Add(2,
    12. New Items With
    13. {
    14. .Zeit = New List(Of Integer) From {4, 5, 1},
    15. .Name = New List(Of String) From {"jkl", "def", "mno"}
    16. }
    17. )
    18. Dim Minimum As Integer
    19. 'so etwas in der Art würde ich gerne machen:
    20. 'Minimum = TestHash.Item.Zeit.Min
    21. 'momentan komme ich so sehr umständlich ans Ziel:
    22. Dim Hilfsliste As New List(Of Integer)
    23. Dim MinHilfsliste As New List(Of Integer)
    24. For Each Key In TestHash.Keys
    25. Hilfsliste = TestHash.Item(Key).Zeit
    26. MinHilfsliste.Add(Hilfsliste.Min)
    27. Next
    28. Minimum = MinHilfsliste.Min
    29. Dim MinKey As Integer
    30. For Each Key In TestHash.Keys
    31. If TestHash.Item(Key).Zeit.Contains(Minimum) Then
    32. MinKey = Key
    33. Exit For
    34. End If
    35. Next
    36. 'hier bekomme ich die Rückmeldung, dass keine "2" vorhanden sei, so funktioniert's also auch nicht????
    37. If TestHash.ContainsValue(2) Then
    38. Dim a As Boolean = True
    39. End If
    40. End Sub
    41. End Class
    42. Public Class Items
    43. Public Property Zeit As List(Of Integer)
    44. Public Property Name As List(Of String)
    45. End Class


    Ich würde gerne so etwas in der Art machen:
    Minimum = TestHash.Item.Zeit.Min

    Und über ContainsValue trotz Liste einen Key ausgegeben bekommen.

    Kann mir da jemand weiterhelfen?

    LG und schon einmal vielen Dank,
    Milena
    Ich finde auch, ein Dictionary wäre wahrscheinlich besser.
    Ansonsten halt so

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim minidx = ht.Cast(Of DictionaryEntry).
    2. ToDictionary(Function(nt) CInt(nt.Key),
    3. Function(nt) DirectCast(nt.Value, items)).
    4. Aggregate(Function(l1, l2) _
    5. If(l1.Value.Zeit.Min < l2.Value.Zeit.Min, l1, l2)).Key
    6. Dim minval = ht.Cast(Of DictionaryEntry).
    7. ToDictionary(Function(nt) CInt(nt.Key),
    8. Function(nt) DirectCast(nt.Value, items)).
    9. Aggregate(Function(l1, l2) _
    10. If(l1.Value.Zeit.Min < l2.Value.Zeit.Min, l1, l2)).
    11. Value.Zeit.Min


    Im Prinzip würde auch ein HashSet, ListOfT etc. funktionieren. Man könnte auch was eigenes machen.
    Ist es den notwendig, dass ein "Key" mitgeführt wird? Reicht der Index der Listen oder Arrays nicht?

    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „exc-jdbi“ ()

    Vielen Dank für die schnellen Antworten.

    Ich habe das "Dictionary" einmal ausprobiert, aber bleibe dort an den gleichen Stellen hängen, wie auch bei Hashtable. Eine kurze Minimumbestimmung bzw. ContainsValue ist dort bei Listen im Dictionary allerdings auch nicht möglich?

    @exc-jdbi: Ich bin durch dein Beispiel leider noch nicht ganz durchgestiegen, da mir die Kenntnisse zum "Dictionary" noch fehlen :/ Wofür stehen denn l1 und l2 in diesem Fall?

    Ich habe bei meinen Daten mit denen ich später weiterarbeiten muss, folgende Darstellung:
    NummerZeitName
    12abc
    15def
    16ghi
    24jkl
    25def
    21mno


    Und ich brauche immer alle Einträge zu der jeweiligen "Nummer" im weiteren Ablauf. Zuerst muss ich allerdings die gewollte "Nummer" über ein Minimum bzw. einen bestimmten Wert in einer der Listen auswählen können.Ich hatte bereits einen Entwurf mit ListOfT erstellt, allerdings bin ich dann fast nur am Abfragen von Indizes beschäftigt, da ich häufig unterschiedliche "Nummern" benötige, woraufhin mir der Hashtable empfohlen wurde.

    VG Milena
    Doch möglich ist alles und ich kann dir nur empfehlen auf die Dictionary oder auf einer
    ganz normalen ListOfT umzusteigen.

    Die Art wie ich das Löse nennt sich LINQ. Natürlich könnte man das alles auch über For (Each) Schleifen lösen.
    Für kleinere Tables oder Listen hat sich jedoch LINQ ganz gut bewährt.

    Man könnte auch was eigenes machen, dafür werden aber gute Programmierkenntnisse benötigt.

    Bleiben wir mal bei deiner HashTable.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim ht = New Hashtable From {
    2. {1,
    3. New MyItems With {
    4. .Zeit = {2, 5, 6}.ToList,
    5. .Name = {"abc", "def", "ghi"}.ToList
    6. }
    7. },
    8. {2,
    9. New MyItems With {
    10. .Zeit = {4, 5, 1}.ToList,
    11. .Name = {"jkl", "mno", "pqr"}.ToList
    12. }
    13. },
    14. {3,
    15. New MyItems With {
    16. .Zeit = {3, 7, 9}.ToList,
    17. .Name = {"stu", "vwx", "yz€"}.ToList
    18. }
    19. }
    20. }
    21. 'Das hier wäre also eine Dictionary(Of int32, MyItems)
    22. Dim tmpdict = ht.Cast(Of DictionaryEntry).
    23. ToDictionary(Function(nt) CInt(nt.Key),
    24. Function(nt) DirectCast(nt.Value, MyItems))
    25. 'So lässt sich der "Key" ermitteln, in dem die kleinste Wert
    26. 'vorhanden ist.
    27. Dim minkey = tmpdict.
    28. Aggregate(Function(l1, l2) _
    29. If(l1.Value.Zeit.Min < l2.Value.Zeit.Min, l1, l2)).Key
    30. 'So lässt sich der kleinste Wert in der Hashtable extrahieren
    31. Dim minval = tmpdict.
    32. Aggregate(Function(l1, l2) _
    33. If(l1.Value.Zeit.Min < l2.Value.Zeit.Min, l1, l2)).
    34. Value.Zeit.Min

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class MyItems
    2. Public Property Zeit As List(Of Int32)
    3. Public Property Name As List(Of String)
    4. End Class

    Für die "Max"-Werte analog vorgehen

    Enumerable.Aggregate Method
    docs.microsoft.com/de-de/dotne…rue&view=netframework-4.8
    Hier wird die Akkumulatorfunktion angewendet. in L1,L2 sind KeyValuePair(Of Int32, MyItems)
    Dadurch bekommst du die Möglichkeit für den Vergleich von L1 und L2

    Aggregate gibt aber gleichzeitig nach erfolgtem Vergleich wieder ein KeyValuePair(Of Int32, MyItems) zurück,
    woraus sich dann der Key oder eben Value.Zeit.Min ermitteln lässt

    Hier habe ich noch ein Rezept wie man die 'Contains ermittelt

    VB.NET-Quellcode

    1. 'Contains (If ... Then)
    2. '**********************
    3. '- Caste zuerst die Values der Hashtable zu deinem Typ Items
    4. '- Mit "Where" können die einzelnen Values (Zeit) mit Contains(x)
    5. ' abgefragen werden auf True, und schauen ob die Liste.Count >0
    6. 'Contains Index (Gehört in die if Then Contains von oben)
    7. '********************************************************
    8. '- Wenn Contains (If ... Then) = true
    9. '- Die gecasteten Dictionary mit "Where" und die einzelnen
    10. ' Values(Zeit) mit Contains(x) abfragen
    11. '- Nun den ersten Item aus der Liste nehmen und Key ausgeben



    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „exc-jdbi“ ()