_Array2DSortFree äöü richtig sortieren

  • Hi,

    ich würde gerne mit _Array2DSortFree ein Array sortieren.

    Verwende ich als 3. Parameter True, so wird nichts sortiert.

    Verwende ich als 3. Parameter False, so steht ä am Ende des Arrays

    Verwende ich _ArraySort passt es.

    Ist da in _Array2DSortFree ein Fehler drin?

  • Sehe ich das richtig?: Du möchtest ein 2D-Array sortieren und dies einfach nur so, dass erst nach der ersten Spalte und dann nach der zweiten sortiert wird?

    Und dafür verwendest du eine Funktion die um diese Aufgabe zu lösen, SQLite durchstartet, eine Datenbank anlegt, Tabellen anlegt, die Tabellen befüllt, die Sortiervorschrift für Sqlite aufarbeitet, in Sqlite sortiert, die Daten wieder aus Sqlite ausliest und Sqlite wieder runterfährt?

    Wahnsinn der Aufwand für so ne popelige Aufgabe.

    Sortierfunktionen mit denen man absolut frei ist wie man sortiert gibt es auch in reinem AutoIt.

    Alles was man da übergeben muss ist eine eigene Vergleichsfunktion die beim Vergleich zweier Arrayelemente zurückgibt ob Element A größer (Return 1), gleich (Return 0) oder kleiner (-1) als Element B ist.

    Mit der UDF sieht dein Beispiel so aus:

  • OK, kann sein, dass es auch anders geht.

    Mit der _Array2DSortFree ist es am benutzerfreundlichsten da ich keine Vergleichsfunktion schreiben muß.

    BugFix

    was meinst du zu dem Thema?

    • Offizieller Beitrag

    BugFix

    was meinst du zu dem Thema?

    Ein Frühwerk von mir ;).

    Meine Intention für diese Funktion lag eigentlich nicht im Sortieren einer Spalte (dafür ist es deutlich overdressed :P). Ich hatte etliche Versuche unternommen mehrstufig zu Sortieren (wie z.B. in Excel: Hauptkriterium Spalte A, darin Sortieren nach B und darin Sortieren nach C - oder ähnlich). Im reinen Array-Sortiermodus ist das m. M. nach nur mit sehr hohem Aufwand realisierbar. Und somit lohnt sich der Aufwand bei mehrstufiger Sortierung durchaus.

    Was deine Sortierprobleme angeht stimme ich dem Link von AspirinJunkie zu. Mit einem Überladen der Sortierfunktion kann man das Problem dann wohl lösen. Ich schreibs mal als Notiz auf meine Agenda - rechne aber nicht mit schneller Realisierung, ich habe im Moment zu viele offene Baustellen.

  • Meine Intention für diese Funktion lag eigentlich nicht im Sortieren einer Spalte (dafür ist es deutlich overdressed :P). Ich hatte etliche Versuche unternommen mehrstufig zu Sortieren (wie z.B. in Excel: Hauptkriterium Spalte A, darin Sortieren nach B und darin Sortieren nach C - oder ähnlich). Im reinen Array-Sortiermodus ist das m. M. nach nur mit sehr hohem Aufwand realisierbar. Und somit lohnt sich der Aufwand bei mehrstufiger Sortierung durchaus.

    Klar, ich will _Array2DSortFree auch dazu verwenden um mehrere Spalten zu sortieren.

    Im reinen Array-Sortiermodus ist das m. M. nach nur mit sehr hohem Aufwand realisierbar. Und somit lohnt sich der Aufwand bei mehrstufiger Sortierung durchaus.

    Welcher Aufwand lohnt sich? Deine _Array2DSortFree zu verwenden oder sich eine eigene Funktion wie AspirinJunkie zu schreiben?

  • Klar, ich will _Array2DSortFree auch dazu verwenden um mehrere Spalten zu sortieren.

    Welcher Aufwand lohnt sich? Deine _Array2DSortFree zu verwenden oder sich eine eigene Funktion wie AspirinJunkie zu schreiben?

    So wie ich das verstehe bräuchtest du wohl eine eigene Kollationstabelle die du irgendwie mit in die Sqlite-Lib mit verwursteln musst.

    Keine Ahnung wie hoch der Aufwand hierfür ist - für mich klingt er jedoch hoch.

    Warum genau scheust du dich eine eigene Vergleichsfunktion anzugeben?

    So böse ist das gar nicht.

    Hier mal ein Beispiel um ein 2D-Array nacheinander von der ersten zur letzten Spalte zu sortieren:

    Code
    Func _mycompare($A, $B)
        For $i = 0 To UBound($A) - 1
            If $A[$i] = $B[$i] Then ContinueLoop
            Return $A[$i] > $B[$i] ? 1 : -1
        Next
        Return 0
    EndFunc

    Die Funktion bekommt die gerade jeweils zu vergleichende Arrayzeilen in $A und in $B als 1D-Array (mit den Spaltenelementen) übergeben und muss nur alle Spalten abgehen.

    Und für andere Fälle bist du damit auch gleich vorbereitet - du kannst ja alles beliebig sortieren wie du möchtest.

    Das klassische NaturalSort ist damit z.B. total einfach.

  • AspirinJunkie

    Hier hast du übrigens einen Fehler drin:

    Local $a_Temp, $d_Ret, $b_Ret - sind im If-Zweig deklariert, $a_Temp wird auch und $b_Ret wird nur im Else-Zweig benutzt, doch dort sind sie nicht deklariert!

    Und im Performancevergleich _ArrayAdd - _DynArrayPush könntest du den Code im Spoiler in Code-Tags setzen, der steht da nämlich als Einzeiler drin.

  • aha, und wie sortiere ich nach Spalte 1 aufsteigend, dann Spalte 3 absteigend, dann Spalte 2 aufsteigend?

    So:

    Hier hast du übrigens einen Fehler drin:

    Local $a_Temp, $d_Ret, $b_Ret - sind im If-Zweig deklariert, $a_Temp wird auch und $b_Ret wird nur im Else-Zweig benutzt, doch dort sind sie nicht deklariert!

    Dann ist es implizit Dim - auch ok.

    Aber bei der nächsten Änderung werde ich das mit glattziehen. - danke dir! - du scheinst viele Karotten zu essen.

    Edit: Welche Version der UDF hast du denn gecheckt? - in meiner (die ich gerade runtergeladen habe) ist das so gar nicht drin wie bei dir dargestellt.

    Dort sind alle Variablen korrekt mit Local in ihrem jeweiligen Scope deklariert.

    Du musst also irgendeine hornsalte Version vorliegen haben.

    Edit 2: Beispiel angepasst - aber unbedingt >>aktualisierte UDF<< runterladen!
    Habe anhand dieses Beispieles einen ziemlich heftigen Fehler bei der Pivot-Bestimmung des Dual-Pivot Quicksorts innerhalb der Funktion gefunden.
    Der machte diesen entweder lahm oder ließ ihn alternativ abstürzen!

    Einmal editiert, zuletzt von AspirinJunkie (16. Juni 2020 um 07:59)

  • Welche Version der UDF hast du denn gecheckt? - in meiner (die ich gerade runtergeladen habe) ist das so gar nicht drin wie bei dir dargestellt.

    Dort sind alle Variablen korrekt mit Local in ihrem jeweiligen Scope deklariert.

    Du musst also irgendeine hornsalte Version vorliegen haben.

    Die Version, die gestern noch bei >>aktualisierte UDF<< angeboten wurde.

    Da sah die Funktion noch so aus:

    In größeren Scripts füge ich zwecks Test diese Zeile ein, und wenn alles ok ist, kommentiere ich sie wieder aus.

    #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

    Jetzt mach das mal in einem Script, in dem DynArray.au3 included wird.

    AutoIt: Press Strg + 5 (Test Run)
    #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
    
    #include "DynArray.au3"

    Ich kann aber in einem Script alle Includes aus c:\Program Files (x86)\AutoIt3\Include\ laden, ohne dass eine Warnung oder ein Fehler angezeigt wird.

    all_Includes_Test.au3

    3 Mal editiert, zuletzt von Bitnugger (16. Juni 2020 um 12:52)

  • Die Version, die gestern noch bei >>aktualisierte UDF<< angeboten wurde.


    Da sah die Funktion noch so aus:

    Heute morgen habe ich diesen Stand runtergeladen - alles i.O.

    Ich hab den Stand vom 17.03.2020 hier vorliegen - das war der vorher letztmals geänderte Stand (Siehe Ältere Versionen des Beitrages).

    Hier ist es alles ebenso korrekt so wie es sein soll.

    Das älteste was ich jetzt hier an diesem Rechner vorliegen habe ist vom 9.3.20 - auch dort ist alles korrekt deklariert.
    Und vom Gefühl her, dass ich an der _DynArraySort() was geändert habe muss tatsächlich schon mehrere Jahre her sein.

    Du musst also aus irgendeinem Grund tatsächlich irgendeine alte Datei vorliegen gehabt haben.

    Edit: Habe jetzt noch eine Version von August 2016 gefunden - auch da sieht die _DynArraySort nicht so aus wie in deinem Screenshot.

    Edit2: Warte mal - kann es sein dass wir aneinander vorbei reden? Kann es sein, dass der Screenshot den du gepostet hast eine Version ist, die du bereits angepasst hast?

    Und der Grund dafür sind diese AutoItWrapper-Meldungen?

    Falls ja - die Meldungen sind Bullshit. Er merkt nicht, dass die Variable nur einmal deklariert ist - entweder im If-oder im Else-Zweig - nie gleichzeitig. Er rafft das jedoch nicht und meldet dann fälschlicherweise already declared - dem ist jedoch nicht so.

    Die anderen Hinweise zu unbenutzten Variablen werde ich jedoch noch einarbeiten - aber die Sache mit dem already declared werde ich nicht ändern - das ist ein Bug vom Au3Wrapper und daher sehe ich nicht ein meinen korrekten Code auf desssen Belange hinzubiegen.

    Edit 3: unbenutzte Variablen aus DynArray-UDF entfernt

    3 Mal editiert, zuletzt von AspirinJunkie (16. Juni 2020 um 14:25)

  • Warte mal - kann es sein dass wir aneinander vorbei reden? Kann es sein, dass der Screenshot den du gepostet hast eine Version ist, die du bereits angepasst hast?

    Wenn ich sie angepasst hätte, würde der Au3Wrapper nicht mehr meckern... und dann hätte ich meinen ersten Beitrag hier gar nicht geschrieben. ;)

    Möglich wäre es aber schon, doch normalerweise füge ich meinen Nick im Header bei Modified ein und hänge an die Zeilen, die ich geändert oder hinzugefügt habe, einen Kommentar an, lasse die originalen Zeilen aber als Kommentar drin, wenn ich in einer fremden UDF etwas ändere.

    Die Funktion sähe dann in etwa so aus:

    aber die Sache mit dem already declared werde ich nicht ändern

    Ich verstehe dich und gebe dir auch recht mit dem Au3Wrapper... sein dämliches Gemeckere wäre aber leicht vermeidbar, indem alle Variablen innerhalb einer Funktion nur einmalig an einer Stelle deklariert werden.

    Ich bin jedenfalls generell der Meinung, dass es eh kein guter Stil ist, Variablen innerhalb von Schleifen Do...Until, While...Wend, For...Next, oder einer If...Then...Else...Endif-Anweisung zu deklarieren.

    Ich habe etwa 5 Minuten für die Änderungen in der aktuellen Version gebraucht, damit Au3Wrapper nicht mehr meckert. Im Anhang die geänderte Version... ohne zusätzliche Kommentare/Hinweise.

  • Ich bin jedenfalls generell der Meinung, dass es eh kein guter Stil ist, Variablen innerhalb von Schleifen Do...Until, While...Wend, For...Next, oder einer If...Then...Else...Endif-Anweisung zu deklarieren.

    Dies habe ich mir in meiner C/C++ - Zeit angewöhnt. Dort ist der verbreitete Grundsatz (Siehe die Werke von Scott Meyers): "Variablen so spät wie möglich deklarieren".

    Sprich: Dort ist es gerade guter Stil.

    Man kann gern darüber diskutieren inwiefern die dem zugrundeliegenden Argumente auch bei AutoIt greifen aber primär steht hierbei für mich folgendes im Vordergrund:

    Wenn ich es nicht machen würde, hätte ich schnell zig Fälle von "declared, but not used in func" ohne das dieser AutoItWrapper dies mitbekommt, da er schlicht nicht in der Lage ist Programmabläufe zu analysieren und stattdessen nur stupide schaut ob zwischen Func und EndFunc die selbe Zeichenkette nochmal auftaucht.

    Kurz: Auf diese Art vermeide ich real existierende "Fehler", welche der AutoItWrapper nicht zu erkennen in der Lage ist und nehme dafür Falschmeldungen über real nichtexistente Fehler in Kauf.

    sein dämliches Gemeckere wäre aber leicht vermeidbar, indem...

    Täter-Opfer-Umkehr? ;)

    Sein dämliches Gemeckere wäre vermeidbar wenn er nicht mehr dämlich agieren würde.
    Ich sehe nicht ein winziges bisschen ein warum ich meinen Programmierstil (der eben auf verbreiteten Grundsätzen beruht) an einen Bug in einem anderen Programm anpassen muss, welches für den Betrieb meines Programmes völlig irrelevant ist.

    Wirst du von irgendwem mit vorgehaltener Waffe gezwungen den AutoItWrapper zu verwenden?

    Vor allem - wirst du gezwungen den mit Parameter "-3 " aufzurufen obwohl bekannt ist, dass der dies nicht korrekt auflösen kann?

    Einmal editiert, zuletzt von AspirinJunkie (17. Juni 2020 um 07:33)

  • Wirst du von irgendwem mit vorgehaltener Waffe gezwungen den AutoItWrapper zu verwenden?

    Vor allem - wirst du gezwungen den mit Parameter "-3 " aufzurufen obwohl bekannt ist, dass der dies nicht korrekt auflösen kann?

    Es geht dabei weniger um mich, sondern um die Leute, für die ich Scripte schreibe... wenn irgendwas nicht stimm, kann ich schlecht hingehen und sagen, dass der Mr. XY daran schuld ist. Das nervt dann einfach nur... und ich sagte ja, ich verstehe deinen Standpunkt und es ist auch nicht weiter von Belang, wenn du es nicht ändern möchtest... finde es nur irgendwie schade, dass ich bei jeder neuen Version Hand anlegen muss, damit meine Schäfchen sich ruhig verhalten. Nun gut, jeder hat das Recht auf seine eigene Meinung... deine kenne ich jetzt, und du ja auch meine, das Thema ist somit durch und wir bleiben Freunde, bis ans Ende unsere Tage ;)

    Variablen so spät wie möglich deklarieren

    Da ist was dran... hat er evtl. auch gesagt, das man so wenig wie möglich Variablen deklarieren sollte? Denn in einigen Funktionen benutzt du für quasi dieselbe Aufgabe im If- und im Else-Zweig zwei verschiedene.

    Z.B.: _DynArraySort: $d_Ret und $b_Ret... hat das einen speziellen Grund?

  • Ich bin jedenfalls generell der Meinung, dass es eh kein guter Stil ist, Variablen innerhalb von Schleifen Do...Until, While...Wend, For...Next, oder einer If...Then...Else...Endif-Anweisung zu deklarieren.

    Täter-Opfer-Umkehr? ;)

    [...]
    Ich sehe nicht ein winziges bisschen ein warum ich meinen Programmierstil (der eben auf verbreiteten Grundsätzen beruht) an einen Bug in einem anderen Programm anpassen muss, welches für den Betrieb meines Programmes völlig irrelevant ist.

    (OT)

    Könnte man sich ggf. darauf einigen, dass es hinsichtlich 'Guter Programmierstil" einen allgemeinen und einen sprachabhängigen Bereich gibt ;)?

    In z.B. AutoIt verwende ich, wie viele andere auch, Typenpräfixe (also $aArr, $sString usw.). In Pascal mache ich das nicht, da dort die Variablen typisiert werden müssen (MaxPos : Integer;).

    Das ist wie im realen Leben. Es gibt meines Wissens keine Kultur in der man es schätzt, wenn einem in die Kronjuwelen getreten wird. Auf den sozialistischen Bruderkuss kann ich, aus ästhetischen und auch hygienischen Gründen, allerdings herzlich gerne verzichten :P.

    Gruß Musashi

    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."

  • Da ist was dran... hat er evtl. auch gesagt, das man so wenig wie möglich Variablen deklarieren sollte? Denn in einigen Funktionen benutzt du für quasi dieselbe Aufgabe im If- und im Else-Zweig zwei verschiedene.

    Z.B.: _DynArraySort: $d_Ret und $b_Ret... hat das einen speziellen Grund?

    Also als erstes wird in diesen Fall immer nur eine Variable zur Laufzeit deklariert und eben nicht mehrere.

    Und ja in diesem Fall habe ich mir tatsächlich etwas dabei gedacht (kommt nicht immer vor!).

    Der Präfix d hat sich bei mir über die Jahre implizit als "Digit" eingebürgert (ja ich weiß - widerspricht der ungarischen Notation als auch der AutoIt-Abwandlung von dieser). Ich kennzeichne hiermit primär Integervariablen (jaja - number statt digit wäre logischer).

    Da _ArraySort  0 oder 1 zurückgibt wird daher dessen Ergebnis in $d_Ret geschmissen.

    Anders bei der _ArraySortFlexible - diese gibt True oder False zurück. Daher wird deren Return-Value in $b_Ret (b = boolean bei mir) weggespeichert.

    Variablen so spät wie möglich deklarieren

    Da ist was dran...

    Oftmals wird diese Praxis sogar noch verschärft zu: "Variablen erst deklarieren wenn man sie auch definieren kann"

    Aber Mehrfachdeklarierungen sollten logischerweise dennoch vermieden werden (z. B. in Schleifen).

    Es geht dabei weniger um mich, sondern um die Leute, für die ich Scripte schreibe...

    Es gibt Leute die verlangen, dass deine Skripte durch den AutoItWrapper durchlaufen müssen?

    Ich hoffe du wirst von denen dann wenigstens anständig bezahlt.

    Könnte man sich ggf. darauf einigen, dass es hinsichtlich 'Guter Programmierstil" einen allgemeinen und einen sprachabhängigen Bereich gibt ;) ?

    Ich sage ja noch nichtmal, dass mein Programmierstil ein guter ist.
    Die Sachen hier schreibe ich ohne Zwang als Hobby - da mache ich das wie ich es für richtig halte.

    Und vor allem halte ich mich nicht mal streng an meine eigenen Regeln - das mache ich je nach Tagslaune auch mal anders.
    In Projekten mit mehreren sehe ich ein, dass sich auf einen Standard geeinigt werden muss. Hier habe ich diesen Zwang jedoch nicht.

    Aber ich sehe das wie du: Ungarische Notation bei typisierten Sprachen mache ich ebenso nicht.