Abruf von Werten in mehrdimensionalen Dictionary's (Dictionary (Of ..., Dictionary (Of ..., ...))

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

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von ThomasG82.

    Abruf von Werten in mehrdimensionalen Dictionary's (Dictionary (Of ..., Dictionary (Of ..., ...))

    Moin,

    vermutlich ist es ganz einfach allerdings kostet es mich schon den halben Tag alle meine Nerven.

    Ich habe ein "verschachteltes" Dictionary. Dictionary (Of String, Dictionary (Of String, Boolean)). Werte eintragen ist alles ok.

    Jetzt brauche ich aber Werte aus dem 2. Dictionary - also STRING und BOOLEAN.
    Dafür habe ich mir ein Dictionary (Of String, Boolean) erstellt und will das ganze einfach dort hinein kopieren. DICTIONARY = DICTIONARY funktioniert ja, wenn beide vom Typ her gleich sind.
    Nun muss ich aber den ersten Key bestimmen und alles was dahinter steckt herausbekommen. Aber ich kann weder die Werte zählen noch bekomme ich irgendetwas raus.

    VB.NET-Quellcode

    1. DIM GrosseSammlungDaten As Dictionary (Of String, Dictionary (Of String, Boolean))
    2. DIM tempSammlungDaten As Dictionary (Of String, Boolean)
    3. tempSammlungDaten.Add("ObjektWert1", TRUE)
    4. tempSammlungDaten.Add("ObjektWert2", TRUE)
    5. tempSammlungDaten.Add("ObjektWert3", FALSE)
    6. GrosseSammlungDaten.Add("Objekt1", tempSammlungDaten)
    7. GrosseSammlungDaten.Add("Objekt2", tempSammlungDaten)
    8. GrosseSammlungDaten.Add("Objekt3", tempSammlungDaten)
    9. 'Jetzt hab ich das Dictionary mit 3 Objekte und je Objekt 3 Werten (Key und Value)
    10. tempSammlungDaten.Clear() 'wird später erneut benötigt
    11. 'Benötigt werden die Werte vom 2. Objekt
    12. For i As Integer = 0 To GrosseSammlungDaten.Values("Objekt2").Keys.Count - 1
    13. tempSammlungDaten ...
    14. Next


    Ich zähle also erstmal wieviele VALUES sich mit dem KEY("Objekt2") im Dictionary befinden .. dachte ich jedenfalls - da kommt immer 0 raus ???
    Und dann müsste ich sie kopieren ... einfach ???
    Ich habe auch GrosseSammlungDaten.Item("Objekt").Keys.Count probiert (dachte ja - weil ich die KEYS zählen will) aber dann löscht er alles was zum Objekt2 gehört???

    Kann mir da bitte jemand helfen.
    tempSammlungDaten.Clear() wird wohl alles löschen was drin ist. Ist das gewünscht?

    Allgemein kann ich denn Sinn deines Vorhabens nicht nachvollziehen. Sieht mir eher nach einem workaround aus... Lässt sich das nicht schön übersichtlich in eine eigener Klasse abbilden die deine benötigten Informationen beherbergt?
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Ja ist gewollt.
    Im realen Code sind es mehrere Dateien die eingelesen werden und die temp wird ja immer wieder benutzt.
    Ich habe mich ja für das ineinander gestapelte Dictionary entschieden aufgrund einer Idee von einen anderem Thema von mir hier.
    Und im Prinzip ist es ja ne gute Idee, da ich alle Infos in einer Variable habe und nicht mit tausend verschiedenen hantieren muss.
    Es sind insgesamt 37 Objekte mit jeweils bis zu 7 Werten und jeder Wert ist entweder TRUE oder FALSE. Somit wären es ja zig tausend einzelne List oder Arrays die haben müsste. Und dafür würden ja solche Verschachtelungen erfunden. Und ich wollte lieber ein Dictionary als ein Array nutzen aufgrund der Fähigkeiten.
    Sorry, versteh deinen Ansatz nicht... verschachtelte Dictionarys sind strange...

    Wie wäre es, ein Dictionary mit einem Tuple?

    VB.NET-Quellcode

    1. Dictionary(Of String, Tuple(Of Object, Boolean))
    Dann kannste per String (Key) auf den Tuple zugreifen welcher dein Objekt und dein Boolean enthält.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Muss ich mir mal anschauen - allerdings finde ich gerade die Erklärung eines Tulpe<T1,T2> echt heavy 8o
    Ach so - die Objekte sind keine Object - es sind bloß physisch und namentlich Objekte - im Code aber Strings (also Namen).

    Ich glaube ich hab es auch so einigermaßen hinbekommen - also eigentlich komplett - komm nur noch nicht dazu meine Werte ordentlich umzusortieren.

    VB.NET-Quellcode

    1. 'temporäre Variable, welche alle Keys enthält
    2. For Each GesuchtesObjekt As String In GrosseSammlungDaten.Keys
    3. 'prüfen - ist der aktuelle Key der gesuchte Wert
    4. If GesuchtesObjekt = "Objekt2" Then
    5. 'die Daten des 2. Dictionary(Of String, Boolean) herauskopieren
    6. For Each WertePaar As KeyValuePair(Of String, Boolean) In GrosseSammlungDaten(GesuchtesObjekt)
    7. 'hineinkopieren in das Ziel Dictionary, mit dem wird weiter gearbeitet (ist Public)
    8. tempSammlungDaten.Add(WertePaar.Key, WertePaar.Value)
    9. 'das funktioniert leider noch nicht
    10. Next
    11. End If
    12. Next


    Mein Problem ist jetzt bloß noch die Daten aus dem Temporären Dictionary in das Ziel Dictionary zu kopieren.
    Wenn ich eine Pause einlege werden mir auch die Werte angezeigt in WertePaar aber ich kann sie nicht nutzen ???
    Kurzer Einwurf: Das mit den Tuples geht doch einfacher: Dim GrosseSammlungDaten As Dictionary (Of String, (String, Boolean))
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    schau dir das mit dem Tuple an... find ich einfacher.

    Mal grundsätzlich zur Arbeit mit Dictionarys:

    1. GrosseSammlungDaten.ContainsKey(„Wert“) liefert dir nen Boolean ob ein Eintrag mit diesem Key vorhanden ist

    2. GrosseSammlungDaten(„Wert“) liefert dir direkt deinen Value (in deinem Fall einen anderes Dictionary ). Falls der Key nicht vorhanden ist gibts nen Fehler. Daher vorher prüfen siehe 1.

    3. Durch ein Dictionary muss man für gewöhnlich nicht interieren. Das liefert dir direkt die Werte. Z.b.

    VB.NET-Quellcode

    1. if(Not GrosseSammlungDaten.ContainsKey(„Foo“)) Then Exit Sub
    2. Dim tmp As Dictionary (Of String, Dictionary (Of String, Boolean)) = GrosseSammlungDaten(„Foo“)
    3. If(Not tmp.ContainsKey(„bla“)) Then Exit Sun
    4. Dim b as Boolean = tmp(„bla“)


    Edit: Code ist so aus dem Kopf per Handy. Daher nicht zwangsläufig lauffähig. Sollte aber die Grundsätze vermitteln.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @VaporiZed - muss ich mir wirklich mal genauer anschauen. Bei Microsoft.Docs fand ich es schon kompliziert erklärt. Wenn es wirklich so einfach geht wie du es aufgezeigt hast, dann ist es doch kein Hexenwerk. :)

    @mrMo - danke. Meinen Fehler hatte ich schon gefunden. Als ich die tempSammlungDaten eröffnet hatte habe ich sie nur als Dictionary (Of String, Boolean) und nicht als New Dictionary (Of String, Boolean) deklariert. Siehe da - 3 Buchstaben mehr und schon klappt auf einmal alles super einfach.
    Durch deinen Code habe ich nun auch die For Each Schleifen gespart - hast natürlich recht - eigentlich muss man das gar nicht so umständlich machen. Danke daher für die Hilfe, der Abend ist gerettet.

    Hier nochmal das Endergebnis - du hattest ein [Dictionary (Of String], zu viel im Code.

    VB.NET-Quellcode

    1. tempSammlungDaten = GrosseSammlungDaten("Objekt2")

    (noch mal kurz überarbeitet - brauch ja gar kein tmp - tempSammlungDaten ist ja schon erstellt)

    Das gute ist, dass ich somit ein Dictionary mit allen Funktionen behalte und es später auch einfach wieder einfügen kann. Ich finde (wenn man diesen Schritt herausgefunden hat) ist es sehr einfach die Daten darin zu verändern, egal wie weit man es verschachtelt hat.
    DANKE euch beiden :D :thumbsup:

    Zum nach verfolgen für die Interessierten - einmal komplett
    Spoiler anzeigen

    VB.NET-Quellcode

    1. DIM GrosseSammlungDaten As New Dictionary (Of String, Dictionary (Of String, Boolean))
    2. DIM tempSammlungDaten As New Dictionary (Of String, Boolean)
    3. tempSammlungDaten.Add("ObjektWert1", TRUE)
    4. tempSammlungDaten.Add("ObjektWert2", TRUE)
    5. tempSammlungDaten.Add("ObjektWert3", FALSE)
    6. GrosseSammlungDaten.Add("Objekt1", tempSammlungDaten)
    7. GrosseSammlungDaten.Add("Objekt2", tempSammlungDaten)
    8. GrosseSammlungDaten.Add("Objekt3", tempSammlungDaten)
    9. 'Jetzt hab ich das Dictionary mit 3 Objekte und je Objekt 3 Werten (Key und Value)
    10. 'Benötigt werden die Werte vom Objekt2 im tempSammlungDaten
    11. tempSammlungDaten = GrosseSammlungDaten("Objekt2")
    12. 'bzw der gesuchte Key und die nachfolgenden Werte
    13. tempSammlungDaten = GrosseSammlungDaten(gesuchterKey)


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

    VB.NET-Quellcode

    1. DIM GrosseSammlungDaten As New Dictionary (Of String, Dictionary (Of String, Boolean))
    2. DIM tempSammlungDaten As New Dictionary (Of String, Boolean)
    3. tempSammlungDaten.Add("ObjektWert1", TRUE)
    4. tempSammlungDaten.Add("ObjektWert2", TRUE)
    5. tempSammlungDaten.Add("ObjektWert3", FALSE)
    6. GrosseSammlungDaten.Add("Objekt1", tempSammlungDaten)
    7. GrosseSammlungDaten.Add("Objekt2", tempSammlungDaten)
    8. GrosseSammlungDaten.Add("Objekt3", tempSammlungDaten)
    9. 'Jetzt hab ich das Dictionary mit 3 Objekte und je Objekt 3 Werten (Key und Value)
    10. tempSammlungDaten.Clear() 'wird später erneut benötigt somit erstmal leeren (und Arbeitsspeicher freigeben)
    11. 'Benötigt werden die Werte vom Objekt2 im tempSammlungDaten
    12. tempSammlungDaten = GrosseSammlungDaten("Objekt2")
    das wird so nicht funktionieren, weil du dasselbe tempSammlungDaten 3 mal in GrosseSammlungDaten reintust.
    So wirst du auch immer dasselbe Dictionary herausbekommen, egal, ob du es über "Objekt1", 2 oder 3 abrufst.
    Und wenn du tempSammlungDaten dann noch Clearst, wirst du dich wundern, dass alle deine Dictionaries auf einmal mitgecleart sind.

    Btw: Kann es sein, du hast den falschen Code in den Spoiler gepackt.?
    @ErfinderDesRades - das mit dem Clear() habe ich auch entfernt. Aus mir unerfindlichen Gründen hat es später immer wieder Fehler gegeben, glaube aber das hat sich durch den Tipp von @mrMo auch erledigt.

    Ich muss ja die tempSammlungDaten auch gar nicht mehr löschen. Aufgrund des Tipps und der Endlösung übernehme ich ja das Dictionary (Of String, Boolean) direkt aus dem Großen ins Temporäre und somit überschreibe ich alles was sich intern befindet.

    Das was ich am Anfang hineintue gliedert sich wie folgt (Datenausgabe wird durch anderes Programm vorgegeben und muss daher so genutzt werden wie es vorliegt).

    Alle Objektnamen befinden sich in einer Datei -> Objektsammlung.txt
    Für jedes Objekt gibt es eine Datei, in welcher die jeweiligen Werte stehen -> Objekt1_Werte.txt ...... Objekt37_Werte.txt
    Daher muss ich ja erst einmal die erste TXT Datei einlesen und sehe aufgrund dessen, was ich noch benötige. Deswegen war auch meine Frage nach der dynamischen Zuweisung von Variableninhalten als Variablennamen.
    Denn ich weiß ja nicht wie viele Objekte da sind und somit wonach ich suchen muss.
    Wie das Ganze dann im Prinzip aussieht sieht man im Bild im Anhang.
    Es ist also schwierig hier den ganzen Code zu Spoilern, da gehört so viel zueinander, das würde wohl den Rahmen sprengen.

    Aber um die Frage mal kurz zu klären: Nein der Spoiler ist richtig und funktioniert auch.
    "Objekt2", welches hier gesucht und kopiert wird ist nur das Beispiel im Beispiel. CodeMäßig müsste es natürlich lauten:
    tempSammlungDaten = GrosseSammlungDaten(GesuchterKey)
    Sprich:
    kopiertesDictionaryOfStringBoolean = OrigrinalDictionaryOfStringOfStringBoolean(KeyDerGesuchtWird)
    Habe auch gerade nochmal getestet - egal was vorher im tempSammlungDaten stand - es wird alles gelöscht und nur die aktuelle Version kopiert (egal ob mehr oder weniger Werte - somit entstehen keine falschen Werte) [hab den Spoiler dementsprechend nochmal geändert und das .Clear() entfernt]
    Bilder
    • DatenSammlung.png

      54,95 kB, 373×681, 86 mal angesehen