Datensätze als Array of struct speichern

  • Für mein aktuelles Projekt machte ich mir gerade darüber Gedanken, wie ich die Datensätze im Programm verwalten will und kam zu dem Schluß, dass ein "Array of struct" eigentlich ganz gut dafür geeignet ist.

    Vor allem sieht man im Quelltext dann auch gleich welche Daten wo liegen, weil man sie über die Punktnotation ansprechen kann. Das ist gegenüber einem 2D-Array ein großer Vorteil.

    Aber auch das Laden und Speichern der Daten ist so viel unkomplizierter. Vielleicht könnt ihr das ja auch gebrauchen...

    Hier mal ein Beispiel dazu:

  • Coole Sache 👍

  • Danke ! Auch von mir den :thumbup::)

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Ja, das ist eine sehr schöne Idee. Auf Structs bin ich an der Stelle noch nicht gekommen. Ich nehme dafür - je nach Komplexitätsgrad - folgende Wege:

    1. Index-Konstanten mit Enum

    Code
    Global Enum $ID, $LASTNAME, $FORENAME, $BIRTHDAY
    Global $aData[2][$BIRTHDAY + 1]
    $aData[0][$LASTNAME] = "Schwahfel"
    $aData[0][$FORENAME] = "Heribert"
    $aData[0][$BIRTHDAY] = "2022-11-09"

    2. Array of Dictionary

    Code
    Global $aoData[2]
    $aoData[0] = ObjCreate("Scripting.Dictionary")
    $aoData[0]("LastName") = "Schwahfel"
    $aoData[0]("ForeName") = "Heribert"
    $aoData[0]("Birthday") = "2022-11-09"

    Habe den Code jetzt gerade aus dem Kopf runtergetippt. Es ist gerade kein Windows mit Au3 greifbar. ^^

    Aber solche Methoden können die Lesbarkeit des Codes um einiges erhöhen.

  • Die Variante mit den Structs / Enumeration unterscheided sich prinzipiell von der Variante mit dem Dictionary dahingehend, dass bei ersterem eine feste Datenstruktur vorgegeben ist - und zwar sowohl hinsichtlich der Attribute, deren Namen als auch deren Typ.
    Bei der Dictionary-Variante ist man hingegen flexibel, welche Attribute gesetzt werden können und kann dann hinterher wild die Datentypen mischen.

    Ersteres benötigt etwas mehr Schreibarbeit, da man ja die Struktur erst definieren muss, ermöglicht jedoch - wie oben gezeigt - eine platzsparende Speichermöglichkeit, da man gleich binär alles hintereinander schreiben kann.
    Beim Datenaustausch muss man hier jedoch noch aufpassen, dass man keine Pointer-Typen in der Struct hat. Wenn man z.B. die Daten auf einem 64Bit-System geschrieben hat, dann würde das Einlesen auf einem 32Bit-System scheitern. Aber wie gesagt: sollte eigentlich nur passieren, wenn man Pointer-Typen hat.

    Wenn es hingegen nur um die Dot-Notation geht, dann kann man dies auch mit Maps erreichen.
    Man muss im Grunde nur folgenden Teil im Skript ändern (und die Struct-Definition kann man sich dann natürlich auch sparen):

    AutoIt
    For $i = 0 To UBound($g_aWorker) - 1
        Local $mTemp[]
        $g_aWorker[$i] =$mTemp
    Next

    Zum Speichern und Auslesen der Daten auf der Platte braucht es dann aber ein anderes Format.
    Beispielsweise json, yaml und Konsorten.

    Von der Performance her wäre, die Map-Variante die fixere von beiden nach meinen Tests (Erstellen ca. 2x und Auslesen ca. 4x)

    Einmal editiert, zuletzt von AspirinJunkie (10. November 2022 um 07:06)

  • Hmm, wusste noch nicht das das geht, muss ich mir für das nächste Mal merken.

    Aber ein Frage, auch wenn es nur ein Beispiel ist, wäre bei PLZ nicht int anstatt char besser?

  • Vielleicht eine Blöde Frage aber gibt es wie beim normalen Array hoerbei auch die Möglichkeit dies "einfach" (wie z.B. _Filewritefromarray()) in eine Datei zu speichern oder muss ich mir dann eine entsprechende Routine dafür selber bauen?

  • Weil das normale "_ArraySort" kein "Array of struct" sortieren kann (ich aber eine Sortierung brauche), habe ich mal eine QuickSort-Funktion hinzugefügt:

  • Blöde (schnelle) Frage.

    Weiß jemand ob ich auch direkt auf etwas zugreifen kann ohne das Array of Struct zu durchlaufen?

    Evtl. ist etwas sample-Code besser um zu verstehen was ich meine:

    Einmal editiert, zuletzt von Moombas (13. Februar 2023 um 10:29)

  • Naja du machst ja eine Bedingungsabfrage.
    Willst also die Objekte haben, welche eine bestimmte Eigenschaft besitzen.
    Das geht in einem einzelnen AutoIt-Aufruf nicht.

    Du könntest eine Funktion schreiben in die deine Schleife verpackt wird und du so die Filterung erreichst.

    Oder du nimmst statt einem Array eine Map und verwendest dort als Schlüssel die ID.
    Auf die Art kannst du schnell per ID auf die einzelnen structs zugreifen:

  • Hi AspirinJunkie : Ich glaube ich war doch etwas ungenau. Ich wollte die '3' bei deiner Zeile 24 eben nicht, da ich diese "nicht weiß", sondern über die ID ermitteln und dann den zugehörigen tag .name ausgeben.

    Ich habe/hatte die Hoffnung das es dafür etwas gibt, ohne das man eine Schleife durchlaufen muss und es relativ simpel abfragbar ist und ich es nur nicht weiß wie.

    Habe es nun aber erst mal über eine Schleife gelöst.

  • Ich wollte die '3' bei deiner Zeile 24 eben nicht, da ich diese "nicht weiß", sondern über die ID ermitteln und dann den zugehörigen tag .name ausgeben.

    Ich weiß. Deshalb habe ich bei der Erstellung der Map die ID als Key verwendet.
    Sprich: Wenn du auf das Element mit dem Key "3" zugreifst - erhälst du die Struktur mit der ID=3.