• Offizieller Beitrag

    Hi,
    da es ja doch so nach und nach immer mehr wird, habe ich mich entschlossen mal alle meine Array-UDF's in eine "ArrayMore.au3" zu packen.

    Falls noch mehr hinzukommt, werde ich dies hier aktualisieren.

    Edit 30.12.2013
    Bugs in _Array2DEmptyDel() und _Array2DDblDel() beseitigt. Aktuelle Version: v 0.4

    EDIT 25.07.07
    Es ist doch einiges hinzugekommen, bzw. wurden die Funktionen, die bisher nur mit 1D-Arrays arbeiteten (oder Dim 2 begrenzt auf 2) erweitert auf 2D ohne Begrenzung.

    <<NEU>>
    Die Calltips für alle hier aufgeführten Funktionen, inklusive Löschfunktion für die Tipps der vorigen Version im Programm: "SetCallTip.au3".

    NEU 23.02.08:
    - Hinzugefügt: _Array2DAdd, _Array2DPop, _Array2DPush
    - Calltipps aktualisiert

    Edit 02.03.08
    Die Datenbank hatte mein Edit verschluckt :D, also nun nochmal:
    - ein Bug in _Array2DDblDel beseitigt (nur das erste Doppel wurde bereinigt)
    - alle Variablen lokal deklariert (nun dürfte kein Fehler mehr bei Verwendung von Opt('MustDeclareVars') auftreten.

    Edit 17.05.08
    Durch die neue Prod 3.2.12.0 einige kleine Veränderungen in den Funktionen:
    - _ArraySort_2ary
    - _Array2DSortByLen

    Edit 05.11.08
    - neue Funktion: _Array2DMinMax()
    - noch nicht in die ArrayMore.au3 eingebunden
    - vorerst hier zu finden


    _ArraySort_2ary()
    sortiert 2D Arrays mehrstufig (z.B. nach Spalte 1 und für gleiche Werte in 1 wird nach Spalte 2 sortiert)
    Habe dazu eine alternative, leistungsfähigere Version erstellt, die mit SQLite arbeitet.
    _Array2DSortFree()
    Die aktuelle Version, hier im selben Thread, Post 15
    Diese Funktion kann aber nicht in die ArrayMore.au3 integriert werden - Erklärung s. hier

    _Array2DSortByLen()
    sortiert 1D/2D Arrays nach Länge der Einträge

    _Array2DDblDel()
    entfernt doppelte Einträge in 1D/2D Arrays

    _Array2DInsert()
    fügt 1 Element (leer oder mit Daten) an gegebener Position ein
    arbeitet mit 1D/2D Arrays

    _Array2DSplit()
    splittet 1D/2D Arrays ab gegebener Position in 2 Arrays
    optional wird eine Anzahl Elemente in ein Zielarray exportiert

    _Array2DEmptyDel()
    löscht leere Zeilen; in 2D Arrays Zeilen oder optional Spalten

    _Array2DJoin()
    verbindet 2 Arrays zu einem, 1D/2D -Arrays, auch untereinander
    Größe der 2.ten Dimension muß nicht übereinstimmen
    ab Prod 3.2.12.0 eine ähnliche Standard-UDF - aber nur für 1D-Arrays: _ArrayConcatenate()

    _Array2DDelete()
    löscht eine Zeile aus einem 1D/2D -Array am gegebenen ZeilenIndex

    _Array2DSearch()
    sucht nach allen oder einmaligem Auftreten des Suchbegriffs in einem 1D/2D -Array
    ein Array mit dem/den gefundenen Index(es) wird zurückgeliefert
    ab Prod 3.2.12.0 eine vergleichbare Standard-UDF: _ArrayFindAll()

    _Array2DMirror()
    spiegelt ein 2D-Array, Zeilen werden zu Spalten und umgekehrt

    _SubArray2DGetEntry()
    gibt den Wert eines Elements aus einem 1D/2D-Array als Element eines 1D/2D-Arrays zurück

    _SubArray2DSetEntry()
    setzt den Wert eines Elements in einem 1D/2D-Array als Element eines 1D/2D-Arrays

    _Array2DAdd()
    fügt einen Eintrag einem 1D/2D-Array am Ende hinzu
    Spaltenwerte in 2D-Arrays sind durch '|' zu trennen
    wird die Funktion ohne Wertübergabe aufgerufen, wird die Arraygröße um 1 erhöht

    _Array2DPop()
    gibt den letzten Wert eines 1D/2D-Arrays zurück und löscht ihn gleichzeitig vom Array
    Arraygröße wird dabei um 1 verringert

    _Array2DPush()
    fügt Einzelwerte oder Arrays in 1D/2D-Arrays ein ohne deren Größe zu verändern
    es kann vom Anfang oder vom Ende eingefügt werden, überzählige Elemente werden 'herausgeschoben'
    (in etwa wie bei LIFO und FIFO in Registern)

    DL bisher: 1430

  • auch netter rang:

    Gesperrt: Er wusste zu viel...


    =D

    Stimme aus dem Hintergrund: "Wenn du noch lange so weitermachst, machst du nicht mehr lange so weiter!" :D


    omg, ich höre Stimmen...Die ignorier ich mal lieber :D

    Einmal editiert, zuletzt von huggy (24. Juni 2007 um 12:51)

  • Hi BugFix
    hast du deine _ArrayDisplay2D in deiner arraymore vergessen :D

    Wäre nicht schlecht, wenn du diesen Tread auch noch in deine Sig mit aufnehmen könntest ;)

  • Ah, dies ist natürlich nicht schlecht.
    Muß ich gleich mal testen ;)

    Danke :D

    EDIT:
    Habe gerade deine Funktion "_Array2DSearch" gebraucht.
    Einwandfrei muß ich sagen :D

    Kannst du diese noch in deine Arraymore hinzufügen?

    Achso noch was:
    Wenn du mal Zeit und Lust hast :D kannst du als :rock:Array-Gott :rock: mal schauen, ob du folgendes schaffst:
    Filelisttoarray mit mehreren Dateitypen (az. B. jpg und avi) :D

    • Offizieller Beitrag
    Zitat

    Wenn du mal Zeit und Lust hast großes Grinsen kannst du als Array-Gott mal schauen, ob du folgendes schaffst:
    Filelisttoarray mit mehreren Dateitypen (az. B. jpg und avi)

    Das würdest sogar du schaffen ;) . Also wenn ich das richtig verstehe, möchtest du mehrere WildCards gleichzeitig anwenden.
    - Liste mit Wildcards übergeben
    - FileListToArray für jedes Element ausführen
    - Arrays zusammenfügen

    Willst du mal probieren ? Wenn nicht mach ich es, kein Problem.

  • Bisher habe ich dies immer so gemacht:

    Eines meiner Beispiel, läuft nicht, da es nur ein Ausschnitt ist:

    Alle Dateien einlesen in ein 1D-Array
    Dateien mit meinen Kriterien rausfiltern und in ein neues 2D-Array schreiben (dazu noch das Datum)
    dann die leeren Zeilen löschen

    Spoiler anzeigen
    [autoit]

    ...
    ;Array ($Filelist) erzeugen (nur Dateinamen)
    Dim $array_quelle = 0
    $anzahl = DirGetSize($Quellordner, 3)
    Dim $array_quelle[$anzahl[1] + 1][2]
    $FileList = _FileListToArray($Quellordner, "*", 1)
    For $i = 1 To UBound($FileList) - 1
    If (StringRight($FileList[$i], 4) = ".jpg") OR (StringRight($FileList[$i], 4) = ".avi") OR (StringRight($FileList[$i], 4) = ".thm") Then
    $array_quelle[$i][0] = $FileList[$i]
    $time2 = FileGetTime($Quellordner & $FileList[$i], 0)
    $array_quelle[$i][1] = $time2[0] & $time2[1] & $time2[2] & $time2[3] & $time2[4] & $time2[5]
    EndIf
    Next

    ;Leere Zeilen löschen
    _Array2DEmptyDel($array_quelle)
    ...

    [/autoit]

    PS: Haste du das mit "_Array2DSearch" gelesen? ;)

    Wie kann ich Arrays zusammenfügen?
    Vor allem 2D-Arrays.

    • Offizieller Beitrag

    Hier mal 2 Beispiele, wie du 1D und 2D-Arrays zusammenfügen kannst.

    Spoiler anzeigen
    [autoit]

    #include <array.au3>
    ; Für 1D-Arrays
    Dim $ar1[6]=[0,1,2,3,4,5]
    Dim $ar2[6]=[10,11,12,13,14,15]
    _ArrayDisplay($ar1, "$ar1")
    _ArrayDisplay($ar2, "$ar2")

    [/autoit] [autoit][/autoit] [autoit]

    ; Array 2 an Array 1 anhängen:
    For $i = 0 To UBound($ar2)-1
    _ArrayAdd($ar1, $ar2[$i])
    Next
    _ArrayDisplay($ar1, "$ar1 + $ar2")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Für 2D-Arrays (Vorkommen in 2.ter Dimension muß bei beiden Arrays identisch sein!)
    Dim $ar1[6][3]
    For $i = 0 To UBound($ar1)-1
    For $k = 0 To UBound($ar1,2)-1
    $ar1[$i][$k] = 'I' & $i & '-' & $k
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Dim $ar2[8][3]
    For $i = 0 To UBound($ar2)-1
    For $k = 0 To UBound($ar2,2)-1
    $ar2[$i][$k] = 'II' & $i & '-' & $k
    Next
    Next
    _ArrayDisplay($ar1, "$ar1")
    _ArrayDisplay($ar2, "$ar2")

    [/autoit] [autoit][/autoit] [autoit]

    ; Array 2 an Array 1 anhängen:
    For $i = 0 To UBound($ar2)-1
    ReDim $ar1[UBound($ar1)+1][3]
    For $k = 0 To UBound($ar2,2)-1
    $ar1[UBound($ar1)-1][$k] = $ar2[$i][$k]
    Next
    Next
    _ArrayDisplay($ar1, "$ar1 + $ar2")

    [/autoit]

    ...und ja, ich habs gelesen. Ich werde die Funktion noch mit hinzufügen. Kommt beim nächsten Edit. Da werde ich noch einige Funktionen komplettieren, dass sie auch für 2D-Arrays mit beliebiger Größe funktionieren.

    • Offizieller Beitrag

    Hi,

    kleiner Bump und noch eine Funktion die evtl. interessant für dich ist:

    Spoiler anzeigen
    [autoit]

    Local $arr[3][3] = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

    _ArrayWalk($arr, '_DumpToConsole')

    Func _ArrayWalk(ByRef $aArray, $sFunction)
    Local $sArrayFetch, $sArrayRead, $bDone
    Local $iSubscripts = UBound($aArray, 0)
    Local $aUBounds[$iSubscripts]
    Local $aCounts[$iSubscripts]
    $iSubscripts -= 1
    For $i = 0 To $iSubscripts
    $aUBounds[$i] = UBound($aArray, $i + 1) - 1
    $aCounts[$i] = 0
    Next
    While 1
    $bDone = True
    $sArrayFetch = ''
    For $i = 0 To $iSubscripts
    $sArrayFetch &= '[' & $aCounts[$i] & ']'
    If $aCounts[$i] < $aUBounds[$i] Then $bDone = False
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $sArrayRead = Execute('$aArray' & $sArrayFetch)
    If @error Then
    ExitLoop
    Else
    Call($sFunction, $sArrayFetch, $sArrayRead)
    If $bDone Then ExitLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    For $i = $iSubscripts To 0 Step - 1
    $aCounts[$i] += 1
    If $aCounts[$i] > $aUBounds[$i] Then
    $aCounts[$i] = 0
    Else
    ExitLoop
    EndIf
    Next
    WEnd
    EndFunc ;==>_ArrayWalk

    [/autoit] [autoit][/autoit] [autoit]

    Func _DumpToConsole($sKey, $vValue)
    ConsoleWrite($sKey & ' => ' & $vValue & @CRLF)
    EndFunc

    [/autoit]

    So long,

    Mega

    • Offizieller Beitrag

    Hier mal noch ein Skript zum Testen für
    _Array2DPop, _Array2DPush
    s. 1. Post

    Spoiler anzeigen
    [autoit]

    #include <array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $a[10], $a2[10][3], $aIn[4], $aIn2[4][3]
    ; Arrays füllen
    For $i = 0 To UBound($a) -1
    If $i < 4 Then
    $aIn[$i] = 'In-Array ' & $i+1
    For $k = 0 To UBound($aIn2, 2) -1
    $aIn2[$i][$k] = 'In-Array ' & $i+1 & ' / ' & $k+1
    Next
    EndIf
    $a[$i] = 'Wert ' & $i+1
    For $k = 0 To UBound($a2, 2) -1
    $a2[$i][$k] = 'Wert ' & $i+1 & ' / ' & $k+1
    Next
    Next
    ; POP 1D-Array
    _ArrayDisplay($a, '1-Dim')
    _ArrayDisplay(_Array2DPop($a), 'Letzter Wert')
    _ArrayDisplay($a, 'Array 1-Dim nach POP')
    ; POP 2D-Array
    _ArrayDisplay($a2, '2-Dim')
    _ArrayDisplay(_Array2DPop($a2), 'Letzter Wert')
    _ArrayDisplay($a2, 'Array 2-Dim nach POP')
    ; PUSH 1D-Array Einzelwert v. rechts
    _ArrayDisplay($a, 'Array 1-Dim vor PUSH')
    _Array2DPush($a, 'Einzel v. Ende')
    _ArrayDisplay($a, 'Array 1-Dim nach PUSH v. rechts')
    ; PUSH 1D-Array Einzelwert v. links
    _Array2DPush($a, 'Einzel v. Anfang', 1)
    _ArrayDisplay($a, 'Array 1-Dim nach PUSH v. links')
    ; PUSH 1D-Array Array v. rechts
    _Array2DPush($a, $aIn)
    _ArrayDisplay($a, 'Array 1-Dim nach PUSH Array v. rechts')
    ; PUSH 1D-Array Array v. links
    _Array2DPush($a, $aIn, 1)
    _ArrayDisplay($a, 'Array 1-Dim nach PUSH Array v. links')
    ; PUSH 2D-Array Array v. rechts
    _ArrayDisplay($a2, 'Array 2-Dim vor PUSH')
    _Array2DPush($a2, $aIn2)
    _ArrayDisplay($a2, 'Array 2-Dim nach PUSH Array v. rechts')
    ; PUSH 2D-Array Array v. links
    _Array2DPush($a2, $aIn2, 1)
    _ArrayDisplay($a2, 'Array 2-Dim nach PUSH Array v. links')

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _Array2DPop($ARRAY)
    ; Description: Gibt das letzte Element eines 1D/2D-Arrays zurück und löscht dieses
    ; gleichzeitig vom Array
    ; Return: Erfolg: 1D = 1D-Array mit dem letzten Element
    ; 2D = 1D-Array mit jeweils einem Eintrag pro Spalte des letzten Elements
    ; Array[0] enthält die Anzahl der Elemente
    ; Fehler: Leerstring und @error = 1 ; Variable ist kein Array
    ; Author(s): Cephas <cephas at clergy dot net>
    ; Modified: BugFix ([email='bugfix@autoit.de'][/email]) ==> 2D-Anpassung
    ;
    ;===============================================================================
    Func _Array2DPop(ByRef $ARRAY)
    Local $LastValue = ''
    Local $UBound2nd = UBound($ARRAY,2), $aOut[1]
    If @error = 1 Then ; kein Array
    SetError(1)
    Return ''
    ElseIf @error = 2 Then ; Array hat keine 2. Dim
    $UBound2nd = 1
    $aOut[0] = $ARRAY[UBound($ARRAY) -1]
    $LastValue = $aOut
    Else
    ReDim $aOut[$Ubound2nd+1]
    $aOut[0] = 0
    For $i = 0 To $Ubound2nd -1
    $aOut[$i+1] = $ARRAY[UBound($ARRAY)-1][$i]
    $aOut[0] += 1
    Next
    $LastValue = $aOut
    EndIf
    If UBound($ARRAY) = 1 Then
    $ARRAY = ''
    Else
    If $UBound2nd = 1 Then
    ReDim $ARRAY[UBound($ARRAY) -1]
    Else
    ReDim $ARRAY[UBound($ARRAY) -1][$UBound2nd]
    EndIf
    EndIf
    Return $LastValue
    EndFunc ;==>_Array2DPop

    [/autoit] [autoit][/autoit] [autoit]

    ;=====================================================================================
    ;
    ; Function Name: _Array2DPush($ARRAY, $Value [, $Direction=0])
    ; Description: Fügt einem Array Werte hinzu ohne die Arraygröße zu verändern.
    ; Werte können vom Ende (Standard) oder vom Anfang des Arrays zugefügt werden.
    ; Entsprechend der Anzahl der einzufügenden Werte wird eine gleiche Anzahl Elemente
    ; aus dem Array 'herausgeschoben' (ge-pusht)
    ; Parameter(s): $ARRAY - Array
    ; $Value - Der einzufügende Wert, oder mehrere Werte als Array
    ; $Direction - 0 = Linksseitiges Schieben (Einfügen vom Ende) (Standard)
    ; 1 = Rechtsseitiges Schieben (Einfügen vom Anfang)
    ; Requirement(s): None
    ; Return Value(s): On Success - Returns 1
    ; On Failure - -1 und SetError
    ; @error = 1 kein Array
    ; @error = 2 Einfügearray größer als Originalarray
    ; @error = 3 Einfügearray und Originalarray haben unterschiedliche Dimensionen @error = 4 $Value ist Einzelwert, 2D-Array erwartet
    ; @error = 5 $Value ist 1D-Array, 2D-Array erwartet
    ; Author(s): Helias Gerassimou(hgeras)
    ; Modified: BugFix ([email='bugfix@autoit.de'][/email]) ==> 2D-Anpassung
    ;
    ;======================================================================================
    Func _Array2DPush(ByRef $ARRAY, $Value, $Direction=0)
    Local $i, $j, $k
    Local $arStatVal = IsArray($Value)
    Local $UBound1st = UBound($ARRAY)
    If @error = 1 Then ; kein Array
    SetError(1)
    Return -1
    EndIf
    Local $UBound2nd = UBound($ARRAY,2)
    If @error = 2 Then ; Array hat keine 2. Dim
    If $arStatVal Then ; Einfügewert ist Array
    Local $UbValue = UBound($Value)
    If $UbValue > $UBound1st Then ; Einfügearray größer als Originalarray
    SetError(2)
    Return -1
    EndIf
    If UBound($Value, 2) > 0 Then
    SetError(3) ; hier keine 2. Dim zulässig
    Return -1
    EndIf
    For $k = 0 To $UbValue -1
    If $Direction = 0 Then
    For $i = 0 To ($UBound1st -2)
    $ARRAY[$i] = $ARRAY[$i+1]
    Next
    $i = ($UBound1st -1)
    $ARRAY[$i] = $Value[$k]
    Else
    For $i = ($UBound1st -1) To 1 Step -1
    $ARRAY[$i] = $ARRAY[$i-1]
    Next
    $ARRAY[$i] = $Value[$UbValue -1 -$k]
    EndIf
    Next
    Else ; Einfügewert ist Einzelwert
    If $Direction = 0 Then ; einfügen Einzelwert vom Ende
    For $i = 1 To $UBound1st -1
    $ARRAY[$i-1] = $ARRAY[$i]
    Next
    $ARRAY[$UBound1st-1] = $Value
    Else ; einfügen Einzelwert vom Anfang
    For $i = $UBound1st-1 To 1 Step -1
    $ARRAY[$i] = $ARRAY[$i-1]
    Next
    $ARRAY[0] = $Value
    EndIf
    EndIf
    Else ; Array ist 2D
    Local $UbValue2nd = UBound($Value, 2)
    If @error = 1 Then ; Einfügewert ist kein Array
    SetError(4)
    Return -1
    ElseIf @error = 2 Then ; Einfügearray nicht 2D
    SetError(5)
    Return -1
    ElseIf UBound($Value) > $UBound1st Then ; Einfügearray größer als Originalarray
    SetError(2)
    Return -1
    ElseIf $Ubound2nd <> $UbValue2nd Then ; 2. Dim nicht identische Größe
    SetError(3)
    Return -1
    EndIf
    Local $UbValue = UBound($Value)
    For $k = 0 To $UbValue -1
    If $Direction = 0 Then
    For $i = 0 To ($UBound1st -2)
    For $j = 0 To $UBound2nd -1
    $ARRAY[$i][$j] = $ARRAY[$i+1][$j]
    Next
    Next
    $i = ($UBound1st -1)
    For $j = 0 To $UBound2nd -1
    $ARRAY[$i][$j] = $Value[$k][$j]
    Next
    Else
    For $i = ($UBound1st -1) To 1 Step -1
    For $j = 0 To $UBound2nd -1
    $ARRAY[$i][$j] = $ARRAY[$i-1][$j]
    Next
    Next
    For $j = 0 To $UBound2nd -1
    $ARRAY[$i][$j] = $Value[$UbValue -1 -$k][$j]
    Next
    EndIf
    Next
    EndIf
    Return 1
    EndFunc ;==>_Array2DPush

    [/autoit]
  • Hi,
    die Funktion _Array2DAdd() ist doppelt vorhanden :D

    Edit: Hiermit behoben, ebenso ein Bug beseitigt - s. erster Post

  • Hi BugFix,
    nun ist die Stable 3.2.12.0 erschienen.
    Nun funktioniert _arraysort nicht mehr.
    Kannste fixen, wenn du Zeit hast :D

    • Offizieller Beitrag

    Hi,
    ich habe nun für die Funktion _ArraySort_2ary eine andere Möglichkeit gefunden, mehrstufig zu sortieren.
    In der neuen Version kann die Art der Sortierung völlig frei gewählt werden. Sortierung ist nicht nur 2-stufig, sondern für alle Spalten möglich.
    Daher auch ein neuer Name: _Array2DSortFree().
    Gerade in der mehrstufigen Sortierung großer Datenmengen ist hierbei ein gewaltiger Geschwindigkeitsvorteil entstanden.
    Diese Features stehen zur Verfügung:
    • Sortierung von 1D-Arrays
    Sortierrichtung Ascending oder Descending
    • Sortierung von 2D-Arrays
    - Sortierung nach ein bis allen Spalten mehrstufig
    - Für jede Spalte wird eine eigene Sortierrichtung angegeben
    - Sortierreihenfolge beliebig kombinierbar
    • Syntax
    _Array2DSortFree($Array2Sort, 'SpaltenIndex|RichtingsIndex,SpaltenIndex|RichtingsIndex')
    _Array2DSortFree($Array2Sort, '0|0,3|1')

    Testet mal schön und gebt mir Feedback. Dann werde ich die Funktion anstelle der _ArraySort_2ary in die ArrayMore.au3 aufnehmen. Leider nicht möglich (s. hier).

    Edit 10.05.2009
    In der aktuellen Stable (3.3.0.0) arbeitet die Funktion _SQLite_Query() fehlerhaft. Habe sie ersetzt mit _SQLite_GetTable2d(), nun funktioniert es auch wieder.

    _Array2DSortFree() mit Bsp.
    [autoit]


    #include <array.au3>
    #include <SQLite.au3>
    #include <SQLite.dll.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Local $a[10][4] = [ _
    [18,4,6,3], _
    [11,5,6,3], _
    [11,6,7,3], _
    [14,4,4,2], _
    [11,5,6,1], _
    [18,4,8,1], _
    [14,3,4,4], _
    [11,5,7,2], _
    [14,4,4,1], _
    [18,4,6,2]]

    [/autoit] [autoit][/autoit] [autoit]

    _Array2DSortFree($a, '0|0,3|1')
    _ArrayDisplay($a, 'Array sortiert, Spalte 0 ASC und innerhalb dann Spalte 3 DESC')

    [/autoit] [autoit][/autoit] [autoit]

    ;==================================================================================================
    ; Function Name: _Array2DSortFree(ByRef $ARRAY, $sCOL_ASC [, $NUM=False])
    ; Description:: Sortierung von 1D/2D-Arrays nach freier Wahl
    ; 1D Sortierung Auf- oder Absteigend
    ; 2D mehrstufige Sortierung, Reihenfolge und Sortier-
    ; richtung (je Spalte) frei wählbar
    ; auch einzelne Spalte sortierbar
    ; Parameter(s): $ARRAY Das zu sortierende Array
    ; $sCOL_ASC String mit Sortierangaben "Spalte|Richtung [, Spalte|Richtung]"
    ; zu sortierende Spalte (0-Index)|Richtung (0-Asc, 1-Desc)
    ; z.B. Spalte 2 aufsteigend und in 2 absteigend Spalte 1
    ; _Array2DSortFree($ar2Sort, '1|0,0|1')
    ; optional $NUM "False" sortiert alphabetisch (Standard), "True" sortiert numerisch
    ; Return Value(s): Erfolg 0
    ; Fehler 1 Set Error 1 $ARRAY ist kein Array
    ; 2 1D-Array, aber Spaltenangabe für 2D
    ; 3 SQL-Fehler
    ; 4 Angaben für Spalte|Sortierrichtung fehlerhaft
    ; Requirements: #include <SQLite.au3>
    ; #include <SQLite.dll.au3>
    ; #include <Array.au3>
    ; Note: Es ist dringend erforderlich, die SQLite-Includes am Beginn des aufrufenden
    ; Skriptes auszuführen. Anderenfalls schlägt die Initialisierung der SQLite.dll
    ; durch _SQLite_Startup() fehl.
    ; Version: 3.3.0.0
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    #include-once
    #include <SQLite.au3>
    #include <SQLite.dll.au3>
    #include <Array.au3>
    Func _Array2DSortFree(ByRef $ARRAY, $sCOL_ASC, $NUM=False)
    If Not IsArray($ARRAY) Then Return SetError(1,0,1)
    Local $tableStr = "CREATE TABLE [tblTEST] ("
    Local $insertStr = '', $insertBase = "INSERT INTO tblTEST VALUES ("
    Local $sortOrder = '', $sortStr = "SELECT * FROM tblTEST ORDER BY "
    Local $aResult, $asc, $iRows, $iCol
    $sCOL_ASC = StringStripWS($sCOL_ASC, 8)
    Local $ub2nd = UBound($ARRAY, 2)
    If @error = 2 Then
    If (StringLen($sCOL_ASC) > 3) Or (StringLeft($sCOL_ASC, 1) <> '0') Then Return SetError(2,0,1)
    If StringRight($sCOL_ASC, 1) = 0 Then
    _ArraySort($ARRAY)
    Else
    _ArraySort($ARRAY, 1)
    EndIf
    Return 0
    Else
    Local $aOut[UBound($ARRAY)][$ub2nd]
    EndIf
    _SQLite_Startup ()
    If @error > 0 Then Return SetError(3,0,1)
    $hSQL = _SQLite_Open ()
    If @error > 0 Then
    _SQLite_Shutdown ()
    Return SetError(3,0,1)
    EndIf
    For $i = 0 To UBound($ARRAY, 2) -1
    $tableStr &= "'field" & $i & "',"
    Next
    $tableStr = StringTrimRight($tableStr, 1) & ");"
    For $i = 0 To UBound($ARRAY) -1
    $insertStr &= $insertBase
    For $k = 0 To UBound($ARRAY, 2) -1
    $insertStr &= "'" & $ARRAY[$i][$k] & "',"
    Next
    $insertStr = StringTrimRight($insertStr, 1) & ");"
    Next
    If _SQLite_Exec ( $hSQL, $tableStr & $insertStr ) <> $SQLITE_OK Then
    _SQLite_Shutdown ()
    Return SetError(3,0,1)
    EndIf
    If StringInStr($sCOL_ASC, ',') Then
    Local $aOrder = StringSplit($sCOL_ASC, ',')
    For $i = 1 To UBound($aOrder) -1
    If StringInStr($sCOL_ASC, '|') Then
    Local $var = StringSplit($aOrder[$i], '|')
    $asc = ' ASC'
    If $var[2] = 1 Then $asc = ' DESC'
    If $NUM Then
    $sortOrder &= 'ABS(field' & $var[1] & ')' & $asc & ','
    Else
    $sortOrder &= 'field' & $var[1] & $asc & ','
    EndIf
    Else
    _SQLite_Shutdown ()
    Return SetError(4,0,1)
    EndIf
    Next
    $sortOrder = StringTrimRight($sortOrder, 1) & ';'
    Else
    If (StringLen($sCOL_ASC) > 2) And (StringInStr($sCOL_ASC, '|')) Then
    Local $var = StringSplit($sCOL_ASC, '|')
    $asc = ' ASC'
    If $var[2] = 1 Then $asc = ' DESC'
    If $NUM Then
    $sortOrder &= 'ABS(field' & $var[1] & ')' & $asc
    Else
    $sortOrder &= 'field' & $var[1] & $asc
    EndIf
    Else
    _SQLite_Shutdown ()
    Return SetError(4,0,1)
    EndIf
    EndIf
    If _SQLite_GetTable2d ( $hSQL, $sortStr & $sortOrder, $aResult, $iRows, $iCol ) <> $SQLITE_OK Then
    _SQLite_Shutdown ()
    Return SetError(3,0,1)
    EndIf
    For $i = 1 To UBound($aResult) -1
    For $j = 0 To UBound($ARRAY,2) -1
    $ARRAY[$i-1][$j] = $aResult[$i][$j]
    Next
    Next
    _SQLite_Exec ($hSQL, "DROP TABLE tblTEST;")
    _SQLite_Close ()
    _SQLite_Shutdown ()
    Return 0
    EndFunc ;==>_Array2DSortFree

    [/autoit]

    Edit:
    Eines fällt mir grad noch ein, die SQLite-Includes müssen zwingend am Anfang des aufrufenden Skripts stehen.
    Ist dies nicht der Fall, kann _SQLite_Startup() nicht die SQLite.dll initialisieren.
    Also die Includes in die Funktions-au3 schreiben geht nicht. Habe bestimmt eine Stunde damit verbracht, diesen Fehler zu lokalisieren.

    DL bisher: 25

    • Offizieller Beitrag

    Hab soeben mal noch an der Performanceschraube gedreht :D und ca. 40 % Geschwindigkeitsgewinn mit der neuen Version.
    Testet mal auf euren PC's, ob da ähnlich Unterschiede sind.
    Hab auf meinem Laptop getestet, Celeron M 1,5 GHz, 448 MB RAM.
    Im Test sortiere ich ein Array mit 2400 Zeilen und 8 Spalten, befüllt mit Zufallszahlen 1 bis 40.
    Sortierung: gemischt und wechselnde Sortierrichtung, aber ALLE Spalten ineinander sortiert.

    Code für Test
    [autoit]

    #include <SQLite.au3>
    #include <SQLite.dll.au3>
    #include <array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Local $b[2400][8]
    For $i = 0 To UBound($b) -1
    For $k = 0 To UBound($b,2) -1
    $b[$i][$k] = Random(1, 40, 1)
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('Variante: _SQLite_GetTable2d' & @CRLF)
    $sum = 0
    $min = 10000
    $max = 0
    $endrun = 20
    For $i = 1 To $endrun
    $start = TimerInit()
    _Array2DSortFree($b, '7|1,1|0,0|1,3|1,5|0,2|0,6|1,4|0')
    $end = TimerDiff($start)
    $sum += $end
    If $end < $min Then $min = $end
    If $end > $max Then $max = $end
    ConsoleWrite($end & ', ')
    If $i = $endrun Then ConsoleWrite(@CRLF)
    Next
    ConsoleWrite('Min: ' & $min & @CRLF)
    ConsoleWrite('Max: ' & $max & @CRLF)
    ConsoleWrite('Durchschnitt: ' & $sum/$endrun & @CRLF & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('Variante: _SQLite_Query + _SQLite_FetchData' & @CRLF)
    $sum = 0
    $min = 10000
    $max = 0
    $endrun = 20
    For $i = 1 To $endrun
    $start = TimerInit()
    _Array2DSort_Free($b, '7|1,1|0,0|1,3|1,5|0,2|0,6|1,4|0')
    $end = TimerDiff($start)
    $sum += $end
    If $end < $min Then $min = $end
    If $end > $max Then $max = $end
    ConsoleWrite($end & ', ')
    If $i = $endrun Then ConsoleWrite(@CRLF)
    Next
    ConsoleWrite('Min: ' & $min & @CRLF)
    ConsoleWrite('Max: ' & $max & @CRLF)
    ConsoleWrite('Durchschnitt: ' & $sum/$endrun & @CRLF) ; ca. 40 % schneller als Variante 1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; erste Version:
    Func _Array2DSortFree(ByRef $ARRAY, $sCOL_ASC)
    If Not IsArray($ARRAY) Then Return SetError(1,0,1)
    Local $tableStr = "CREATE TABLE tblTEST ("
    Local $insertStr = '', $insertBase = "INSERT INTO tblTEST VALUES ("
    Local $sortOrder = '', $sortStr = "SELECT * FROM tblTEST ORDER BY "
    Local $aResult, $iRows, $iColumns, $iRval, $asc
    $sCOL_ASC = StringStripWS($sCOL_ASC, 8)
    Local $ub2nd = UBound($ARRAY, 2)
    If @error = 2 Then
    If (StringLen($sCOL_ASC) > 3) Or (StringLeft($sCOL_ASC, 1) <> '0') Then Return SetError(2,0,1)
    If StringRight($sCOL_ASC, 1) = 0 Then
    _ArraySort($ARRAY)
    Else
    _ArraySort($ARRAY, 1)
    EndIf
    Return 0
    Else
    Local $aOut[UBound($ARRAY)][$ub2nd]
    EndIf
    _SQLite_Startup ()
    If @error > 0 Then Return SetError(3,0,1)
    $hSQL = _SQLite_Open ()
    If @error > 0 Then
    _SQLite_Shutdown ()
    Return SetError(3,0,1)
    EndIf
    For $i = 0 To UBound($ARRAY, 2) -1
    $tableStr &= "'field" & $i & "',"
    Next
    $tableStr = StringTrimRight($tableStr, 1) & ");"
    For $i = 0 To UBound($ARRAY) -1
    $insertStr &= $insertBase
    For $k = 0 To UBound($ARRAY, 2) -1
    $insertStr &= "'" & $ARRAY[$i][$k] & "',"
    Next
    $insertStr = StringTrimRight($insertStr, 1) & ");"
    Next
    If _SQLite_Exec ( $hSQL, $tableStr & $insertStr ) <> $SQLITE_OK Then
    _SQLite_Close ()
    _SQLite_Shutdown ()
    Return SetError(3,0,1)
    EndIf
    If StringInStr($sCOL_ASC, ',') Then
    Local $aOrder = StringSplit($sCOL_ASC, ',')
    For $i = 1 To UBound($aOrder) -1
    If StringInStr($sCOL_ASC, '|') Then
    Local $var = StringSplit($aOrder[$i], '|')
    $asc = ' ASC'
    If $var[2] = 1 Then $asc = ' DESC'
    $sortOrder &= 'field' & $var[1] & $asc & ','
    Else
    _SQLite_Close ()
    _SQLite_Shutdown ()
    Return SetError(4,0,1)
    EndIf
    Next
    $sortOrder = StringTrimRight($sortOrder, 1) & ';'
    Else
    If (StringLen($sCOL_ASC) = 3) And (StringInStr($sCOL_ASC, '|')) Then
    Local $var = StringSplit($sCOL_ASC, '|')
    $asc = ' ASC'
    If $var[2] = 1 Then $asc = ' DESC'
    $sortOrder &= 'field' & $var[1] & $asc
    Else
    _SQLite_Close ()
    _SQLite_Shutdown ()
    Return SetError(4,0,1)
    EndIf
    EndIf
    $iRval = _SQLite_GetTable2d (-1, $sortStr & $sortOrder, $aResult, $iRows, $iColumns)
    If $iRval = $SQLITE_OK Then
    For $i = 1 To UBound($aResult) -1
    For $k = 0 To UBound($aResult,2) -1
    $aOut[$i-1][$k] = $aResult[$i][$k]
    Next
    Next
    Else
    _SQLite_Close ()
    _SQLite_Shutdown ()
    Return SetError(4,0,1)
    EndIf
    _SQLite_Exec ($hSQL, "DROP TABLE tblTEST;")
    _SQLite_Close ()
    _SQLite_Shutdown ()
    $ARRAY = $aOut
    Return 0
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; zweite Version:
    Func _Array2DSort_Free(ByRef $ARRAY, $sCOL_ASC)
    If Not IsArray($ARRAY) Then Return SetError(1,0,1)
    Local $tableStr = "CREATE TABLE tblTEST ("
    Local $insertStr = '', $insertBase = "INSERT INTO tblTEST VALUES ("
    Local $sortOrder = '', $sortStr = "SELECT * FROM tblTEST ORDER BY "
    Local $hQuery, $aRow, $asc, $i, $k
    $sCOL_ASC = StringStripWS($sCOL_ASC, 8)
    Local $ub2nd = UBound($ARRAY, 2)
    If @error = 2 Then
    If (StringLen($sCOL_ASC) > 3) Or (StringLeft($sCOL_ASC, 1) <> '0') Then Return SetError(2,0,1)
    If StringRight($sCOL_ASC, 1) = 0 Then
    _ArraySort($ARRAY)
    Else
    _ArraySort($ARRAY, 1)
    EndIf
    Return 0
    Else
    Local $aOut[UBound($ARRAY)][$ub2nd]
    EndIf
    _SQLite_Startup ()
    If @error > 0 Then Return SetError(3,0,1)
    $hSQL = _SQLite_Open ()
    If @error > 0 Then
    _SQLite_Shutdown ()
    Return SetError(3,0,1)
    EndIf
    For $i = 0 To UBound($ARRAY, 2) -1
    $tableStr &= "'field" & $i & "',"
    Next
    $tableStr = StringTrimRight($tableStr, 1) & ");"
    For $i = 0 To UBound($ARRAY) -1
    $insertStr &= $insertBase
    For $k = 0 To UBound($ARRAY, 2) -1
    $insertStr &= "'" & $ARRAY[$i][$k] & "',"
    Next
    $insertStr = StringTrimRight($insertStr, 1) & ");"
    Next
    If _SQLite_Exec ( $hSQL, $tableStr & $insertStr ) <> $SQLITE_OK Then
    _SQLite_Shutdown ()
    Return SetError(3,0,1)
    EndIf
    If StringInStr($sCOL_ASC, ',') Then
    Local $aOrder = StringSplit($sCOL_ASC, ',')
    For $i = 1 To UBound($aOrder) -1
    If StringInStr($sCOL_ASC, '|') Then
    Local $var = StringSplit($aOrder[$i], '|')
    $asc = ' ASC'
    If $var[2] = 1 Then $asc = ' DESC'
    $sortOrder &= 'field' & $var[1] & $asc & ','
    Else
    _SQLite_Shutdown ()
    Return SetError(4,0,1)
    EndIf
    Next
    $sortOrder = StringTrimRight($sortOrder, 1) & ';'
    Else
    If (StringLen($sCOL_ASC) = 3) And (StringInStr($sCOL_ASC, '|')) Then
    Local $var = StringSplit($sCOL_ASC, '|')
    $asc = ' ASC'
    If $var[2] = 1 Then $asc = ' DESC'
    $sortOrder &= 'field' & $var[1] & $asc
    Else
    _SQLite_Shutdown ()
    Return SetError(4,0,1)
    EndIf
    EndIf
    If _SQlite_Query (-1, $sortStr & $sortOrder, $hQuery) <> $SQLITE_OK Then
    _SQLite_Shutdown ()
    Return SetError(3,0,1)
    EndIf
    $i = 0
    While _SQLite_FetchData ($hQuery, $aRow) = $SQLITE_OK
    For $k = 0 To UBound($ARRAY,2) -1
    $ARRAY[$i][$k] = $aRow[$k]
    Next
    $i += 1
    WEnd
    _SQLite_Exec ($hSQL, "DROP TABLE tblTEST;")
    _SQLite_Close ()
    _SQLite_Shutdown ()
    Return 0
    EndFunc

    [/autoit]


    Für den Testlauf hab ich der neuen Version einen anderen Namen verpaßt, im Anhang ist es derselbe, wie Version 1.

    Edit 17.08.08: Die aktuelle Version ist in Post 15

    • Offizieller Beitrag

    Hi,
    habe eine Erweiterung vorgenommen. Bisher wurde nur alphabetisch sortiert, bedingt durch die Standardsortierfunktion von SQLite.
    Wird jetzt für das Flag $NUM der Wert "True" übergeben, erfolgt die Sortierung numerisch.

    Hier die neueste Version:
    Edit 17.08.08: Die aktuelle Version ist in Post 15