_ArraySort sortiert "komisch"

    • Offizieller Beitrag

    Ich habe Dein Beispiel mal ein wenig angepasst, um die Problematik zu verdeutlichen:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    Dim $array[100][4]
    For $i = 0 To 99
    For $j = 0 To 3
    $array[$i][$j] = Random(0, 10, 1)
    Next
    Next; Array mit Zufallsinhalt erzeugen

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

    _Array2D_Sort($array, 0)
    _ArrayDisplay($array)

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Array2D_Sort
    ; Description ...: Sorts a 2D Array by Index
    ; Syntax.........: _Array2D_Sort($avArray[, $iIndex = 0])
    ; Parameters ....: $avArray - Array to display
    ; $iIndex - [optional] Sort Array by this Index
    ; Return values .: Success - Sorted Array
    ; Failure - 0, sets @error:
    ; |1 - $avArray is not an Array
    ; |2 - $avArray is not an 2D-Array
    ; |3 - $iIndex is out of
    ; Author ........: Schnitzel
    ; Modified.......:
    ; Link ..........: https://autoit.de/index.php?page=Thread&threadID=18117
    ; Example .......: Yes
    ; ===============================================================================================================================

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

    Func _Array2D_Sort(ByRef $avArray, $iIndex = 0)
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)
    If Not UBound($avArray, 0) = 2 Then Return SetError(2, 0, 0)
    If UBound($avArray, 2) <= $iIndex Then Return SetError(3, 0, 0)
    Local $bTausch, $sTmp, $i = 0, $iRuns = UBound($avArray) - 2
    Do
    $bTausch = False
    For $j = 0 To $iRuns - $i
    If $avArray[$j][$iIndex] > $avArray[$j + 1][$iIndex] Then
    For $k = 0 To UBound($avArray, 2) - 1
    $sTmp = $avArray[$j + 1][$k]
    $avArray[$j + 1][$k] = $avArray[$j][$k]
    $avArray[$j][$k] = $sTmp
    Next
    $bTausch = True
    EndIf
    Next
    $i += 1
    Until ($bTausch = False) Or ($i = $iRuns)
    EndFunc ;==>_Array2D_Sort

    [/autoit]


    Wenn jetzt die Werte im ersten Element gleich sind, dann sollen die gleichen nach dem Wert des zweiten Elements sortiert werden. Das ist bei Deiner Funktion nicht der Fall.

  • Zitat

    Wenn jetzt die Werte im ersten Element gleich sind, dann sollen die gleichen nach dem Wert des zweiten Elements sortiert werden. Das ist bei Deiner Funktion nicht der Fall.

    joa ok das kann man ja noch anpassen ;)

  • Moin!


    Was haltet ihr von dieser Version!

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <Timers.au3>
    Dim $Zeilen, $Spalten, $TE,$start
    Dim $Array[3][3] = [['abc', 'a11', '555'],['bcd', 'a11', '444'],['cde', 'a11', '666']]
    Dim $Array1[4][4] = [['abc', 'a11', '555', 'b'],['xcd', 'a11', '444', 'c'],['cde', 'a11', '666', 'd'],['fde', 'a11', '777', 'h']]
    Dim $Array2[9999][3]
    For $i = 0 To 9998
    $Array2[$i][0] = Chr(Random(65, 90, 1)) & Chr(Random(65, 90, 1)) & Chr(Random(65, 90, 1))
    $Array2[$i][1] = Chr(Random(65, 90, 1)) & Random(0, 99, 1)
    $Array2[$i][2] = Random(0, 999, 1)
    Next
    Dim $Array3[100][4]
    For $i = 0 To 99
    For $j = 0 To 3
    $Array3[$i][$j] = Random(0, 10, 1)
    Next
    Next

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

    _ArrayDisplay($Array)
    $start = _Timer_Init()
    $TE = _ArraySort2D($Array)
    _ArrayDisplay($TE,_Timer_Diff($start))

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

    _ArrayDisplay($Array1)
    $start = _Timer_Init()
    $TE = _ArraySort2D($Array1)
    _ArrayDisplay($TE,_Timer_Diff($start))

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

    _ArrayDisplay($Array2)
    $start = _Timer_Init()
    $TE = _ArraySort2D($Array2)
    _ArrayDisplay($TE,_Timer_Diff($start))

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

    _ArrayDisplay($Array3)
    $start = _Timer_Init()
    $TE = _ArraySort2D($Array3)
    _ArrayDisplay($TE,_Timer_Diff($start))

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

    Func _ArraySort2D(ByRef $Array)
    If Not IsArray($Array) Then Return SetError(1, 0, 1)
    $Zeilen = UBound($Array)
    $Spalten = UBound($Array, 2)
    Dim $SubArray[$Zeilen][$Spalten]
    For $i = 0 To $Spalten - 1
    _ArraySort($Array, 0, 0, 0, $i)
    For $e = 0 To $Zeilen - 1
    $SubArray[$e][$i] = $Array[$e][$i]
    Next
    Next
    Return $SubArray
    EndFunc ;==>_ArraySort2D

    [/autoit]

    LG Kleiner

  • bin nochmal kurz drübergegangen. isses so jetzt das was du suchst oscar?

    Spalte 0 hat in jeden index den gleichen wert. nach ihr muss also nicht sortiert werden.
    also wird nach spalte 2 sortiert.

    beim zweiten durchlauf muss in spalte 1 nichts getauscht werden da alle gleich und in spalte 2 wird nichts getauscht weil die ja schon sortiert sind.
    also wird nach spalte 3 sortiert

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Dim $array[100][4]
    For $i = 0 To 99
    For $j = 1 To 3
    $array[$i][$j] = Random(0, 10, 1)
    Next
    Next; Array mit Zufallsinhalt erzeugen

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

    For $i = 0 To 99
    $array[$i][0] = 0
    Next
    _ArrayDisplay($array)

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

    _Array2D_Sort($array, 0)
    _ArrayDisplay($array)

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

    _Array2D_Sort($array, 0)
    _ArrayDisplay($array)

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Array2D_Sort
    ; Description ...: Sorts a 2D Array by Index
    ; Syntax.........: _Array2D_Sort($avArray[, $iIndex = 0])
    ; Parameters ....: $avArray - Array to display
    ; $iIndex - [optional] Sort Array by this Index
    ; Return values .: Success - Sorted Array
    ; Failure - 0, sets @error:
    ; |1 - $avArray is not an Array
    ; |2 - $avArray is not an 2D-Array
    ; |3 - $iIndex is out of
    ; Author ........: Schnitzel
    ; Modified.......:
    ; Link ..........: https://autoit.de/index.php?page=Thread&threadID=18117
    ; Example .......: Yes
    ; ===============================================================================================================================

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

    Func _Array2D_Sort(ByRef $avArray, $iIndex = 0)
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)
    If Not UBound($avArray, 0) = 2 Then Return SetError(2, 0, 0)
    If UBound($avArray, 2) <= $iIndex Then Return SetError(3, 0, 0)
    Local $bTausch, $sTmp, $i = 0, $iRuns = UBound($avArray) - 2
    Do
    $bTausch = False
    For $j = 0 To $iRuns - $i
    If $avArray[$j][$iIndex] > $avArray[$j + 1][$iIndex] Then
    For $k = 0 To UBound($avArray, 2) - 1
    $sTmp = $avArray[$j + 1][$k]
    $avArray[$j + 1][$k] = $avArray[$j][$k]
    $avArray[$j][$k] = $sTmp
    Next
    $bTausch = True
    EndIf
    Next
    $i += 1
    Until ($bTausch = False) Or ($i = $iRuns)
    If ($bTausch = False) And ($i = 1) Then _Array2D_Sort($avArray, $iIndex + 1)
    EndFunc ;==>_Array2D_Sort

    [/autoit]
    • Offizieller Beitrag

    Schnitzel: Ich bin Dir ja dankbar, dass Du Dich an dem Problem versuchst und Deine Funktion ist auch recht schnell, nur passt es noch nicht so ganz.
    Ich habe Dein Beispiel mal etwas verändert, um es genauer zu zeigen:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $max = 500
    Dim $array[$max][3]
    for $i = 0 to $max - 1
    $array[$i][0]= Chr(Random(65,67,1)) & Chr(Random(65,67,1)) & Chr(Random(65,67,1))
    $array[$i][1]= Chr(Random(65,67,1)) & Chr(Random(65,67,1)) & Chr(Random(65,67,1))
    $array[$i][2]= Chr(Random(65,90,1)) & Chr(Random(65,90,1)) & Chr(Random(65,90,1))
    Next
    _ArrayDisplay($array, 'Vorher:')

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

    _Array2D_Sort($array, 0)
    _ArrayDisplay($array, 'Nachher:')

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

    ;~ _Array2D_Sort($array, 1)
    ;~ _ArrayDisplay($array)

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Array2D_Sort
    ; Description ...: Sorts a 2D Array by Index
    ; Syntax.........: _Array2D_Sort($avArray[, $iIndex = 0])
    ; Parameters ....: $avArray - Array to display
    ; $iIndex - [optional] Sort Array by this Index
    ; Return values .: Success - Sorted Array
    ; Failure - 0, sets @error:
    ; |1 - $avArray is not an Array
    ; |2 - $avArray is not an 2D-Array
    ; |3 - $iIndex is out of
    ; Author ........: Schnitzel
    ; Modified.......:
    ; Link ..........: https://autoit.de/index.php?page=Thread&threadID=18117
    ; Example .......: Yes
    ; ===============================================================================================================================

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

    Func _Array2D_Sort(ByRef $avArray, $iIndex = 0)
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)
    If Not UBound($avArray, 0) = 2 Then Return SetError(2, 0, 0)
    If UBound($avArray, 2) <= $iIndex Then Return SetError(3, 0, 0)
    Local $bTausch, $sTmp, $i = 0, $iRuns = UBound($avArray) - 2
    Do
    $bTausch = False
    For $j = 0 To $iRuns - $i
    If $avArray[$j][$iIndex] > $avArray[$j + 1][$iIndex] Then
    For $k = 0 To UBound($avArray, 2) - 1
    $sTmp = $avArray[$j + 1][$k]
    $avArray[$j + 1][$k] = $avArray[$j][$k]
    $avArray[$j][$k] = $sTmp
    Next
    $bTausch = True
    EndIf
    Next
    $i += 1
    Until ($bTausch = False) Or ($i = $iRuns)
    If ($bTausch = False) And ($i = 1) Then _Array2D_Sort($avArray, $iIndex + 1)
    EndFunc ;==>_Array2D_Sort

    [/autoit]


    Mal ganz ohne Zahlen (sind später eh keine Zahlen, sondern Strings). Wenn nun die Buchstabenfolge in der ersten Spalte gleich ist, dann müssen diese Gleichen nach den Buchstaben aus der zweiten Spalte sortiert werden. Nach der dritten Spalte braucht nicht sortiert werden. Diese soll nur anzeigen, dass das 2D-Array noch weitere Spalten besitzt und man diese mitsortieren muss.
    Eine Zeile mit allen Spalten bildet einen Datensatz. Diese dürfen auch nicht auseinandergerissen werden (Hinweis an kleiner27).

    • Offizieller Beitrag

    So, nachdem mir UEZ in der Shoutbox die Gehirnwindungen entknotet hat, konnte ich das Script von ihm in eine Funktion zusammenfassen:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $max = 999
    Dim $array[$max][3]
    for $i = 0 to $max - 1
    $array[$i][0]= Chr(Random(65,67,1)) & Chr(Random(65,67,1)) & Chr(Random(65,67,1))
    $array[$i][1]= Chr(Random(65,67,1)) & Chr(Random(65,67,1)) & Chr(Random(65,67,1))
    $array[$i][2]= Chr(Random(65,90,1)) & Chr(Random(65,90,1)) & Chr(Random(65,90,1))
    Next
    _ArrayDisplay($array, 'Vorher:')
    _NewArraySort($array, 0, 1)
    _ArrayDisplay($array, 'Nachher:')

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

    Func _NewArraySort(ByRef $aSort, $1st, $2nd)
    Local $j = 0, $k = 1
    _ArraySort($aSort, 0, 0, 0, $1st)
    While $k < UBound($aSort)
    If $aSort[$j][$1st] <> $aSort[$k][$1st] Then
    If $k - $j > 1 Then
    _ArraySort($aSort, 0, $j, $k - 1, $2nd)
    $j = $k
    Else
    $j = $k
    EndIf
    EndIf
    $k += 1
    WEnd
    If $k - $j > 1 Then _ArraySort($aSort, 0, $j, $k, $2nd)
    EndFunc

    [/autoit]


    Das ist schön schnell und sortiert richtig. Danke UEZ und nochmal ein Danke an alle anderen.
    Mein Projekt steht nun kurz vor der Fertigstellung. :)