wie spricht man Array im Array direkt an?

  • Hallöchen,

    ich habe mit _GUICtrlListView_GetItemTextArray ( $hLV2 , $iIndex ) ein Array im Array erstellt und wollte jetzt die Array auslesen. So wie ich das versuche klappt das nicht.

    ich kann zwar $aArray = ($avArray)[$i] so zuordnen und $aArray dann auslesen. Gibt es eine bessere Lösung wie ich sowas $avArray[{A20}] ... $avArray[{A21}].....$avArray[{A19}] ( die {A...} sind 1D Arrays)

    geschickt in ein 2D Array überführe.

    Wie spricht man Array im Array direkt an?

    For $i = 0 to UBound($avArray)-1

    _ArrayToClip ( ($avArray)[$i] , "|", 0 , $iRow, @CRLF , 0 , $iCol )

    MsgBox($MB_SYSTEMMODAL, "_ArrayToClip() 2D Test", ClipGet())

    Next

    :/

    ich hoffe, daß ich mein Problem klar genug formuliert habe.

  • Ein kleines Beispiel:

    AutoIt
    Opt('MustDeclareVars', 1)
    #include <Array.au3>
    
    
    Global $aArray1[2] = ["Org Item 0", "Org item 1"]
    Global $aArray2[2] = [0, $aArray1]
    
    _Arraydisplay($aArray2); Zeigt nur an das sich ein Array in $aArray2[1] befindet mittels {Array}
    Consolewrite(($aArray2[1])[0] & @CRLF) ;greift auf das 0. Element im Array, das im "HauptArray"[1] befindet. Ausgabe: Org Item 0
  • Hier ist auch etwas Vorsicht geboten. Es gibt einen Unterschied zwischen "Lesezugriff" und "Schreibzugriff" auf Arrays und Maps. Die Klammernotation funktioniert (bei Arrays) nur für den Lesezugriff. Bei Maps werden die Klammern (meistens) nicht benötigt. Das "meistens" schreibe ich dazu, weil Array/Map Kombinationen scheinbar komplett wahnsinnig sind.

    All diese Tests sind unvollständig (es gibt noch ein paar Syntaxtricks die ich nicht ausprobiert habe), sollten aber einen Überblick darüber geben was geht, und was nicht geht.

    Es ist außerdem (gerade bei den Array/Map Kombinationen) nicht ersichtlich ob es sich hierbei um Bugs handelt oder nicht. Von daher ist jeder "Trick mit Klammern" potentiell irgendwann nicht mehr gültig, die "Hilfsfunktion mit ByRef Version" sollte aber immer funktionieren, auch wenn sie die umständlichste Methode darstellt.

    lg

    M

  • Du kannst dir auch eine Funktion erstellen, die liest und schreibt. Ist manchmal übersichtlicher. Inhaltlich passiert dasselbe, wie bei Mars .

  • Die >>JSON-UDF<< bringt bereits Funktionen mit, die hier weiterhelfen können.
    Der Vorteil der _JSON_addChangeDelete() wäre, dass 1. die gewohnte Syntax - halt in einem String - verwendet werden kann und 2. noch viel komplexere Verschachtelungen - auch mit Maps und Dictionaries - hiermit behandelt werden können.
    Lediglich 2D-Arrays werden noch nicht unterstützt (siehe Edit unten).

    Beispiel hierzu:

    Edit: Die _JSON_Get() kann nun auch mit 2D/3D-Arrays umgehen. Syntaxbeispiel: [2, 3]

    Einmal editiert, zuletzt von AspirinJunkie (2. Juni 2023 um 14:45)

  • Moin,

    kann mir jemand erklären, wofür man diese "Klammernotation" im Zusammenhang mit mehrdimensinalen Arrays brauchen soll? Wenn ich in einem zweidimansionalen Array auf ein bestimmtes Element zugreifen will, brauche ich einen "Zeilenindex" für die erste Dimension und einen "Spaltenindex" für die zweite. Sämtliche Zugriffe auf ein solches Element klappen dann mit: $aArray[$iZeilenIndex][$iSpaltenindex], egal ob lesend oder schreibend. Die Indices müssen allerdings gültig sein.

    Will man das Ganze als Schleife verarbeiten, kann man zwei geschachtelte Schleifen nutzen, z.B

    AutoIt
    For $iZeilenIndex = 0 To UBound($aArray, 1) - 1 ; erste Dimension
        For $iSpaltenIndex = 0 To UBound($aArray, 2) - 1 ; zweite Dimension
            MsgBox(0, "Test", "$aArray[" & $iZeilenIndex & "][" & $iSpaltenIndex & "] = " & $aArray[$iZeilenIndex][$iSpaltenIndex]
        Next
    Next

    Deshalb meine Empfehlung: Bei reinen mehrdimensionalen Arrays den Klammerbeutel im Schrank lassen. ;)

  • Die "reine" multidimensionale Arrays funktioniert das (so sollte es ja auch sein). Bei verschachtelten Arrays funktioniert es aber nicht. Vermutlich wird AutoIt-intern nicht nach jedem Array Indexzugriff via Brackets aktualisiert welche Variable gerade verwendet wird. Ist natürlich nur eine Vermutung, kenne den aktuellen Code von AutoIt ja nicht.

    Bei Maps ist die Sache vollkommen anders. Hier wird nach jedem Index AutoIt-intern ByRef aktualisiert wo man gerade ist. Deshalb kann man beliebig geschachtelte Maps haben und hat immer direkten lese- und Schreibzugriff.

    M

  • Deshalb meine Empfehlung: Bei reinen mehrdimensionalen Arrays den Klammerbeutel im Schrank lassen. ;)

    ....was als Seiteneffekt den Debug-Aufwand bei "fehlerhaften" Zugriffen um 100% reduziert!

    Will man das Ganze als Schleife verarbeiten, kann man zwei geschachtelte Schleifen nutzen, z.B

    Die Quintessenz zum Thema! Es könnte alles sooo einfach sein....

    Letztendlich dreht sich doch alles um n-dimensionale Arrays. Und da sollte man die syntaktisch einfachste und gängigste Syntax verwenden, bei der auch ein Syntax-Parser nicht "verwirrt" werden kann.

    Und ja, Klammern müssen gesetzt werden, um das korrekte "Rechenergebnis" zu erhalten $erg=$a+$b*$c und $erg=($a+$b)*$c

    Aber bei einem relativ simplen 2- bzw- 3-dimensionalen Array diese größtenteils nicht nachvollziehbaren "Klammer-Experimente" im Code zu zelebrieren, nur weil das fancy aussieht, halte ich gelinde gesagt für überflüssig.

    Für Hardliner gibt es glücklicherweise auch debugbare(!) Möglichkeiten, s.

    Die >>JSON-UDF<< bringt bereits Funktionen mit, die hier weiterhelfen können.

    Der Vorteil der _JSON_addChangeDelete() wäre, dass 1. die gewohnte Syntax - halt in einem String - verwendet werden kann und 2. noch viel komplexere Verschachtelungen - auch mit Maps und Dictionaries - hiermit behandelt werden können.

  • Mars & Andy,

    ich danke für Eure Bemühungen. Ich habe das tatsächliche Problem erst nachträglich erkannt. Ich dachte, wenn ein Array in einem Element eines eindimensionalen Arrays abgelegt wird, ergibt das ein zweidimensionales Array. Das ist aber offensichtlich nicht so. Der Klammerbeutel wird ja auch in der Hilfedatei als offizielle Methode für den direkten Zugriff aufgeführt. Mein Fehler! :(

    Wie ich es jetzt verstehe, lautet ursprüngliche Problem: "ListView-Inhalt in 2-dimensionales Array ausgeben". Ich musste dabei wieder einmal feststellen, dass man mit den 'eingebauten' GUI-Funktionen nicht weit kommt, wenn man nicht jede ID der mit GUICtrlCreateListViewItem() erstellten Items speichert. Die mit der AutoIt3.exe gelieferten GUI-Funktionen sind auch hier recht ärmlich. Warum man ein ListView-Item nicht über den Index ansprechen kann, bleibt das Geheimnis des Programmierers.

    Gott sei Dank gibt es aber für diesen speziellen Fall die ControlListView() Funktionen. Damit kann man sich auch ohne UDF's ohne großen Programmieraufwand ein 2-D-Array aus dem ListView erstellen:

    Ich habe nicht geprüft, ob das so schon anderswo eingestellt wurde. Falls ich eine andere 'eingebaute' Alternative übersehen habe, zeigt sie mir bitte.

  • Und wieder schamlose Eigenwerbung von mir!:
    Um aus einem Array-In-Array-Konstrukt ein 2D-Array zu erzeugen (und auch andersherum), kann man ebenso die JSON-UDF nehmen:

  • Und wieder schamlose Eigenwerbung von mir!:

    Und um mich schamlos selbst zu zitieren:

    Es könnte alles sooo einfach sein....

    :thumbup: