Array 2-stufig sortieren

    • Offizieller Beitrag

    Hallo,
    benötigt habe ich es hierfür.

    Da ich es sehr sinnvoll finde, wurde gleich eine Funktion daraus.
    Was tuts?
    - übergebenes (2-Dimensionales) Array wird nach vorgegebener Hauptdimension sortiert
    - innerhalb dieser Dimension erfolgt die Sortierung nach der anderen Dimension
    - wahlweise auf- oder absteigend

    Bsp. s.o. Link


    Edit: Danke Mega für den Hinweis mit ByRef. Hiermit eingebunden. Aufruf somit gewohnt wie bei _ArraySort( ).
    Übrigens, die Lösungsidee kam mir bei der Arbeit mit RegEx. Die Erkennung der zu sortierenden Elemente in der 2.Dimension ist wie bei RegEx ein positiver bzw. negativer Lookahead. ;)

    Edit:
    - Parameter $REVERSE hinzugefügt
    - zweite Dimension kann entgegengesetzt zur ersten sortiert werden

    Edit:
    Arbeitet jetzt mit beliebig vielen Vorkommen in der 2.ten Dimension.

    Spoiler anzeigen
    [autoit]

    ;------------------------------------------------------------------------------------------------------------
    ; Function _ArraySort_2ary(ByRef $ARRAY [, $DIM_1ST=0 [, $DESCENDING=0 [$REVERSE=False]]])
    ;
    ; Description sort an 2D-Array 2-ary
    ; BaseIndex is 0
    ; sort the whole array
    ;
    ; Parameter $ARRAY: Array to sort
    ; optional $DIM_1ST: MainSortIndex; 1st Dim. [0] or last occurence in 2nd Dim.[all other values] (default 0)
    ; optional $DESCENDING: Sort ascending[0]/descending[1] (default 0)
    ; optional $REVERSE: Sort 2nd Dimension reverse to 1st Dimension (default False)
    ;
    ; Return Succes ByRef 2-ary sorted Array
    ; Failure 0 set @error
    ; @error = 1 given array is not array
    ; @error = 2 given array has only 1 dimension
    ;
    ; Requirements By using numeric entry, be sure that type is "number" for correct sort
    ; Works with any occurences in 2nd Dimension
    ;
    ; Author BugFix ([email='bugfix@autoit.de'][/email])
    ;------------------------------------------------------------------------------------------------------------
    #include <Array.au3>
    Func _ArraySort_2ary(ByRef $ARRAY, $DIM_1ST=0, $DESCENDING=0, $REVERSE=False)
    If ( Not IsArray($ARRAY) ) Then
    SetError(1)
    Return 0
    EndIf
    Local $FIRST = 0, $LAST, $tmpFIRST, $sortYES = 0
    Local $UBound2nd = UBound($ARRAY,2)
    If @error = 2 Then
    SetError(2)
    Return 0
    EndIf
    If $DIM_1ST <> 0 Then $DIM_1ST = $UBound2nd-1
    Local $arTmp[1][$UBound2nd]
    _ArraySort($ARRAY,$DESCENDING,0,0,$UBound2nd,$DIM_1ST)
    If $REVERSE Then
    Switch $DESCENDING
    Case 0
    $DESCENDING = 1
    Case 1
    $DESCENDING = 0
    EndSwitch
    EndIf
    For $u = 0 To $UBound2nd-1
    For $i = 0 To UBound($ARRAY)-1
    If $sortYES = 0 Then
    If $u > 0 Then
    If ( $i < UBound($ARRAY)-1 ) And ( $ARRAY[$i][$u] = $ARRAY[$i+1][$u] ) And _
    ( $ARRAY[$i][$u-1] = $ARRAY[$i+1][$u-1] )Then
    $sortYES = 1
    $FIRST = $i
    EndIf
    Else
    If ( $i < UBound($ARRAY)-1 ) And ( $ARRAY[$i][$u] = $ARRAY[$i+1][$u] ) Then
    $sortYES = 1
    $FIRST = $i
    EndIf
    EndIf
    ElseIf $sortYES = 1 Then
    If ( $i = UBound($ARRAY)-1 ) Or ( $ARRAY[$i][$u] <> $ARRAY[$i+1][$u] ) Then
    $sortYES = 0
    $LAST = $i +1
    ReDim $arTmp[$LAST-$FIRST][$UBound2nd]
    $tmpFIRST = $FIRST
    For $k = 0 To UBound($arTmp)-1
    For $l = 0 To $UBound2nd-1
    $arTmp[$k][$l] = $ARRAY[$tmpFIRST][$l]
    Next
    $tmpFIRST += 1
    Next
    $tmpFIRST = $FIRST
    Switch $DIM_1ST
    Case 0
    If $u = $UBound2nd-1 Then
    _ArraySort($arTmp,$DESCENDING,0,0,$UBound2nd,$UBound2nd-1)
    Else
    _ArraySort($arTmp,$DESCENDING,0,0,$UBound2nd,$u+1)
    EndIf
    For $k = 0 To UBound($arTmp)-1
    For $l = 1 To $UBound2nd-1
    $ARRAY[$tmpFIRST][$l] = $arTmp[$k][$l]
    Next
    $tmpFIRST += 1
    Next
    Case $UBound2nd-1
    If $u = $UBound2nd-1 Then
    _ArraySort($arTmp,$DESCENDING,0,0,$UBound2nd,0)
    Else
    _ArraySort($arTmp,$DESCENDING,0,0,$UBound2nd,$UBound2nd-1-$u-1)
    EndIf
    For $k = 0 To UBound($arTmp)-1
    For $l = 0 To $UBound2nd-2
    $ARRAY[$tmpFIRST][$l] = $arTmp[$k][$l]
    Next
    $tmpFIRST += 1
    Next
    EndSwitch
    EndIf
    EndIf
    Next
    $sortYES = 0
    Next
    EndFunc ;==>_ArraySort_2ary

    [/autoit]
  • Hi BugFix
    habe vielleicht einen Fehler festgestellt ?(

    Wenn ich z. b. ein Array mit 4 Spalten habe, und ich sortiere die 2. oder 3. Spalte, dann wird nicht diese, sondern die 4. Spalte sortiert.

    Bsp:

    Spoiler anzeigen
    [autoit]

    #include<Array.au3>
    #include<ArrayMore.au3>

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

    Dim $avArray[5][4]
    $avArray[0][0] = "JPM"
    $avArray[1][0] = "Holger"
    $avArray[2][0] = "Jon"
    $avArray[3][0] = "Larry"
    $avArray[4][0] = "Jeremy"
    $avArray[0][1] = "z"
    $avArray[1][1] = "d"
    $avArray[2][1] = "k"
    $avArray[3][1] = "b"
    $avArray[4][1] = "x"
    $avArray[0][2] = "KB991213"
    $avArray[1][2] = "KB911213"
    $avArray[2][2] = "KB931213"
    $avArray[3][2] = "KB971213"
    $avArray[4][2] = "KB999213"
    $avArray[0][3] = "a"
    $avArray[1][3] = "d"
    $avArray[2][3] = "b"
    $avArray[3][3] = "e"
    $avArray[4][3] = "c"

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

    _ArrayDisplay( $avArray, "original" )
    _ArraySort_2ary($avArray, 0)
    _ArrayDisplay( $avArray, "nach der 1. Spalte sortiert" )
    _ArraySort_2ary($avArray, 1)
    _ArrayDisplay( $avArray, "nach der 2. Spalte sortiert" )
    _ArraySort_2ary($avArray, 2)
    _ArrayDisplay( $avArray, "nach der 3. Spalte sortiert" )
    _ArraySort_2ary($avArray, 3)
    _ArrayDisplay( $avArray, "nach der 4. Spalte sortiert" )

    [/autoit]
    • Offizieller Beitrag

    Die Funktion ist ja nicht dazu gedacht eine bestimmte Spalte zu sortieren (das kann _ArraySort() von Haus aus) sondern mehrstufig zu sortieren.
    Also entweder von links (Index 0) oder rechts (Index Ubound(ar,2)-1) beginnend.
    Um Fehleingaben abzufangen, wird jeder Wert <> 0 als: 'sortiere von rechts nach links' interpretiert.
    So auch die Parametererklärung:

    Zitat

    ; optional $DIM_1ST: MainSortIndex; 1st Dim. [0] or last occurence in 2nd Dim.[all other values] (default 0)