Dim $testArray[8] = ["2.54.0.2", "1.0.0.0", "7.25.11.4", "2.1.0.0", "3.4.15.1", "1.0.0.0", "7.7.7.7", "4.4.4.4"] $msg = "" For $x = 0 To 7 $msg &= $testArray[$x] & @CRLF Next MsgBox(0x1040, "Test", $msg) _ArraySort($testArray, 0, 0, 0, 0, "CustomCompare") $msg = "" For $x = 0 To 7 $msg &= $testArray[$x] & @CRLF Next MsgBox(0x1040, "Test", $msg) Func CustomCompare($left, $right) Local $l = StringSplit($left, ".") Local $r = StringSplit($right, ".") For $x = 1 To 4 $l[$x] = Int($l[$x]) $r[$x] = Int($r[$x]) Next For $x = 1 To 4 If $l[$x] < $r[$x] Then Return -1 ElseIf $l[$x] = $r[$x] Then ContinueLoop Else Return 1 EndIf Next EndFunc ;==>CustomCompare ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArraySort ; Description ...: Sort a 1D or 2D array on a specific index using the quicksort/insertionsort algorithms. ; Syntax.........: _ArraySort(ByRef $avArray[, $iDescending = 0[, $iStart = 0[, $iEnd = 0[, $iSubItem = 0]]]]) ; Parameters ....: $avArray - Array to sort ; $iDescending - [optional] If set to 1, sort descendingly ; $iStart - [optional] Index of array to start sorting at ; $iEnd - [optional] Index of array to stop sorting at ; $iSubItem - [optional] Sub-index to sort on in 2D arrays ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - $avArray is not an array ; |2 - $iStart is greater than $iEnd ; |3 - $iSubItem is greater than subitem count ; |4 - $avArray has too many dimensions ; Author ........: Jos van der Zande ; Modified.......: LazyCoder - added $iSubItem option, Tylo - implemented stable QuickSort algo, ; Modified.......: Jos van der Zande - changed logic to correctly Sort arrays with mixed Values and Strings, ; Modified.......: Ultima - major optimization, code cleanup, removed $i_Dim parameter ; Modified.......: MilesAhead - added user defined $iCompare for generalized qsort() ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArraySort(ByRef $avArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0, $iCompare = "") If Not IsArray($avArray) Then Return SetError(1, 0, 0) Local $iUBound = UBound($avArray) - 1 ; Bounds checking If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound If $iStart < 0 Then $iStart = 0 If $iStart > $iEnd Then Return SetError(2, 0, 0) ; Sort Switch UBound($avArray, 0) Case 1 __ArrayQuickSort1D($avArray, $iStart, $iEnd, $iCompare) If $iDescending Then _ArrayReverse($avArray, $iStart, $iEnd) Case 2 Local $iSubMax = UBound($avArray, 2) - 1 If $iSubItem > $iSubMax Then Return SetError(3, 0, 0) If $iDescending Then $iDescending = -1 Else $iDescending = 1 EndIf __ArrayQuickSort2D($avArray, $iDescending, $iStart, $iEnd, $iSubItem, $iSubMax, $iCompare) Case Else Return SetError(4, 0, 0) EndSwitch Return 1 EndFunc ;==>_ArraySort ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __ArrayQuickSort1D ; Description ...: Helper function for sorting 1D arrays ; Syntax.........: __ArrayQuickSort1D(ByRef $avArray, ByRef $iStart, ByRef $iEnd) ; Parameters ....: $avArray - Array to sort ; $iStart - Index of array to start sorting at ; $iEnd - Index of array to stop sorting at ; Return values .: None ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: MilesAhead - added user defined $iCompare for generalized qsort() ; Remarks .......: For Internal Use Only ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func __ArrayQuickSort1D(ByRef $avArray, ByRef $iStart, ByRef $iEnd, $iCompare = "") If $iEnd <= $iStart Then Return Local $vTmp ; InsertionSort (faster for smaller segments) If ($iEnd - $iStart) < 15 Then Local $vCur For $i = $iStart + 1 To $iEnd $vTmp = $avArray[$i] If $iCompare Then For $j = $i - 1 To $iStart Step -1 If (Call($iCompare, $vTmp, $avArray[$j]) >= 0) Then ExitLoop $avArray[$j + 1] = $avArray[$j] Next ElseIf IsNumber($vTmp) Then For $j = $i - 1 To $iStart Step -1 $vCur = $avArray[$j] ; If $vTmp >= $vCur Then ExitLoop If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop $avArray[$j + 1] = $vCur Next Else For $j = $i - 1 To $iStart Step -1 If (StringCompare($vTmp, $avArray[$j]) >= 0) Then ExitLoop $avArray[$j + 1] = $avArray[$j] Next EndIf $avArray[$j + 1] = $vTmp Next Return EndIf ; QuickSort Local $l = $iStart, $r = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)], $fNum = IsNumber($vPivot) Do If $iCompare Then While (Call($iCompare, $avArray[$l], $vPivot) < 0) $l += 1 WEnd ; While $avArray[$R] > $vPivot While (Call($iCompare, $avArray[$r], $vPivot) > 0) $r -= 1 WEnd ElseIf $fNum Then ; While $avArray[$L] < $vPivot While ($avArray[$l] < $vPivot And IsNumber($avArray[$l])) Or (Not IsNumber($avArray[$l]) And StringCompare($avArray[$l], $vPivot) < 0) $l += 1 WEnd ; While $avArray[$R] > $vPivot While ($avArray[$r] > $vPivot And IsNumber($avArray[$r])) Or (Not IsNumber($avArray[$r]) And StringCompare($avArray[$r], $vPivot) > 0) $r -= 1 WEnd Else While (StringCompare($avArray[$l], $vPivot) < 0) $l += 1 WEnd While (StringCompare($avArray[$r], $vPivot) > 0) $r -= 1 WEnd EndIf ; Swap If $l <= $r Then $vTmp = $avArray[$l] $avArray[$l] = $avArray[$r] $avArray[$r] = $vTmp $l += 1 $r -= 1 EndIf Until $l > $r __ArrayQuickSort1D($avArray, $iStart, $r, $iCompare) __ArrayQuickSort1D($avArray, $l, $iEnd, $iCompare) EndFunc ;==>__ArrayQuickSort1D ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __ArrayQuickSort2D ; Description ...: Helper function for sorting 2D arrays ; Syntax.........: __ArrayQuickSort2D(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax) ; Parameters ....: $avArray - Array to sort ; $iStep - Step size (should be 1 to sort ascending, -1 to sort descending!) ; $iStart - Index of array to start sorting at ; $iEnd - Index of array to stop sorting at ; $iSubItem - Sub-index to sort on in 2D arrays ; $iSubMax - Maximum sub-index that array has ; Return values .: None ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: MilesAhead - added user defined $iCompare for generalized qsort() ; Remarks .......: For Internal Use Only ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func __ArrayQuickSort2D(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax, $iCompare = "") If $iEnd <= $iStart Then Return ; QuickSort Local $vTmp, $l = $iStart, $r = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)][$iSubItem], $fNum = IsNumber($vPivot) Do If $iCompare Then While (Call($iCompare, $avArray[$l][$iSubItem], $vPivot) < 0) $l += 1 WEnd While (Call($iCompare, $avArray[$r][$iSubItem], $vPivot) > 0) $r -= 1 WEnd ElseIf $fNum Then ; While $avArray[$L][$iSubItem] < $vPivot While ($iStep * ($avArray[$l][$iSubItem] - $vPivot) < 0 And IsNumber($avArray[$l][$iSubItem])) Or (Not IsNumber($avArray[$l][$iSubItem]) And $iStep * StringCompare($avArray[$l][$iSubItem], $vPivot) < 0) $l += 1 WEnd ; While $avArray[$R][$iSubItem] > $vPivot While ($iStep * ($avArray[$r][$iSubItem] - $vPivot) > 0 And IsNumber($avArray[$r][$iSubItem])) Or (Not IsNumber($avArray[$r][$iSubItem]) And $iStep * StringCompare($avArray[$r][$iSubItem], $vPivot) > 0) $r -= 1 WEnd Else While ($iStep * StringCompare($avArray[$l][$iSubItem], $vPivot) < 0) $l += 1 WEnd While ($iStep * StringCompare($avArray[$r][$iSubItem], $vPivot) > 0) $r -= 1 WEnd EndIf ; Swap If $l <= $r Then For $i = 0 To $iSubMax $vTmp = $avArray[$l][$i] $avArray[$l][$i] = $avArray[$r][$i] $avArray[$r][$i] = $vTmp Next $l += 1 $r -= 1 EndIf Until $l > $r __ArrayQuickSort2D($avArray, $iStep, $iStart, $r, $iSubItem, $iSubMax, $iCompare) __ArrayQuickSort2D($avArray, $iStep, $l, $iEnd, $iSubItem, $iSubMax, $iCompare) EndFunc ;==>__ArrayQuickSort2D ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArraySwap ; Description ...: Swaps two items. ; Syntax.........: _ArraySwap(ByRef $vItem1, ByRef $vItem2) ; Parameters ....: $vItem1 - First item to swap ; $vItem2 - Second item to swap ; Return values .: None. ; Author ........: David Nuttall ; Modified.......: Ultima - minor optimization ; Remarks .......: This function swaps the two items in place, since they're passed by reference. Regular, non-array variables can also be swapped by this function. ; Related .......: _ArrayReverse ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArraySwap(ByRef $vItem1, ByRef $vItem2) Local $vTmp = $vItem1 $vItem1 = $vItem2 $vItem2 = $vTmp EndFunc ;==>_ArraySwap ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayReverse ; Description ...: Takes the given array and reverses the order in which the elements appear in the array. ; Syntax.........: _ArrayReverse(ByRef $avArray[, $iStart = 0[, $iEnd = 0]]) ; Parameters ....: $avArray - Array to modify ; $iStart - [optional] Index of array to start modifying at ; $iEnd - [optional] Index of array to stop modifying at ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - $avArray is not an array ; |2 - $iStart is greater than $iEnd ; |3 - $avArray is not a 1 dimensional array ; Author ........: Brian Keene ; Modified.......: Jos van der Zande - added $iStart parameter and logic, Tylo - added $iEnd parameter and rewrote it for speed, Ultima - code cleanup, minor optimization ; Remarks .......: ; Related .......: _ArraySwap ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArrayReverse(ByRef $avArray, $iStart = 0, $iEnd = 0) If Not IsArray($avArray) Then Return SetError(1, 0, 0) If UBound($avArray, 0) <> 1 Then Return SetError(3, 0, 0) Local $vTmp, $iUBound = UBound($avArray) - 1 ; Bounds checking If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound If $iStart < 0 Then $iStart = 0 If $iStart > $iEnd Then Return SetError(2, 0, 0) ; Reverse For $i = $iStart To Int(($iStart + $iEnd - 1) / 2) $vTmp = $avArray[$i] $avArray[$i] = $avArray[$iEnd] $avArray[$iEnd] = $vTmp $iEnd -= 1 Next Return 1 EndFunc ;==>_ArrayReverse