代码之家  ›  专栏  ›  技术社区  ›  JonathanDavidArndt

使用AutoIt的用户定义排序比较

  •  1
  • JonathanDavidArndt  · 技术社区  · 6 年前

    PHP有 usort Comparator 接口。


    // Return value:
    //    Negative value: a before b
    //    Positive value: b before a
    //    Zero:           strings are equal
    function compare(String a, String b) {
        return toLowerCase(a) - toLowerCase(b);
    }
    

    ... 你可以很简单,也可以很花哨。


    汽车里有什么东西能做到这一点吗?

    文档很好,帮助文件也很好,但是我找不到任何允许我定义自定义比较函数的东西。(如果有必要,我会重新实现快速排序,但是有了像AutoIt这样功能齐全的框架,我觉得我一定忽略了一些东西。)

    2 回复  |  直到 6 年前
        1
  •  2
  •   user4157124    6 年前

    " "

    _ArrayMultiColSort() :

    #include <Array.au3>
    #include "ArrayMultiColSort.au3"
    
    Global Const $g_sHeaderRow = 'category|value'
    Global Const $g_aSortOrder = [ _
                                    [0, 'critical,important,regular'], _
                                    [1, 1] _
                                 ]
    Global       $g_aArray     = [ _
                                    ['critical',  7], _
                                    ['important', 2], _
                                    ['important', 6], _
                                    ['regular',   2], _
                                    ['critical',  5], _
                                    ['regular',   9] _
                                 ]
    
    _ArrayMultiColSort($g_aArray, $g_aSortOrder)
    _ArrayDisplay($g_aArray, @ScriptName, '', 0, Default, $g_sHeaderRow)
    

    退货:

    critical  7
    critical  5
    important 6
    important 2
    regular   9
    regular   2
    
        2
  •  1
  •   JonathanDavidArndt    6 年前

    虽然AutoIt中似乎没有任何内置内容,但持续的研究揭示了社区创建的几个非常有用的库。

    _ArrayCustomSort.au3 埃里克·皮尔西斯。脚本已复制在本文末尾以供参考。可在以下位置找到原件:

    https://www.autoitscript.com/forum/topic/83626-natural-order-string-comparison/

    用法:

    #include <File.au3>
    #include "_ArrayCustomSort.au3"
    
    ; Directory to list files
    Local $dir = "C:\Windows"
    Local $arr = _FileListToArray($dir, "*")
    _ArrayDelete($arr, 0)
    
    ; Here is the name of the user-defined sorting function!
    _ArrayCustomSort($arr, "_MyBasicStringCompare", 0)
    _ArrayDisplay($arr)
    
    ; Now you can put all your crazy sorting logic in here!
    Func _MyBasicStringCompare($s1, $s2)
       Return StringCompare($s1, $s2)
    EndFunc
    

    包括库:

    #include-once
    #include <Array.au3>
    
    ; #FUNCTION# ====================================================================================================================
    ; Name ..........: _ArrayCustomSort
    ; Description ...: Sort a 1D or 2D array on a specific index using the quicksort/insertionsort algorithms, based on a custom sorting function.
    ; Syntax ........: _ArrayCustomSort(Byref $avArray, $sSortFunc[, $iDescending = 0[, $iStart = 0[, $iEnd = 0[, $iSubItem = 0]]]])
    ; Parameters ....: $avArray             - [in/out] Array to sort
    ;                  $sSortFunc           - Name of custom sorting function. See Remarks for usage.
    ;                  $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
    ;                  |5 - Invalid sort function
    ; Author ........: Erik Pilsits
    ; Modified ......: Erik Pilsits - removed IsNumber testing, LazyCoder - added $iSubItem option, Tylo - implemented stable QuickSort algo, Jos van der Zande - changed logic to correctly Sort arrays with mixed Values and Strings, Ultima - major optimization, code cleanup, removed $i_Dim parameter
    ; Remarks .......: Sorting function is called with two array elements as arguments. The function should return
    ;                  0 if they are equal,
    ;                  -1 if element one comes before element two,
    ;                  1 if element one comes after element two.
    ; Related .......:
    ; Link ..........:
    ; Example .......: No
    ; ===============================================================================================================================
    Func _ArrayCustomSort(ByRef $avArray, $sSortFunc, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0)
        If Not IsArray($avArray) Then Return SetError(1, 0, 0)
        If Not IsString($sSortFunc) Then Return SetError(5, 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
                __ArrayCustomQuickSort1D($avArray, $sSortFunc, $iStart, $iEnd)
                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
    
                __ArrayCustomQuickSort2D($avArray, $sSortFunc, $iDescending, $iStart, $iEnd, $iSubItem, $iSubMax)
            Case Else
                Return SetError(4, 0, 0)
        EndSwitch
    
        Return 1
    EndFunc   ;==>_ArrayCustomSort
    
    ; #INTERNAL_USE_ONLY#============================================================================================================
    ; Name...........: __ArrayCustomQuickSort1D
    ; Description ...: Helper function for sorting 1D arrays
    ; Syntax.........: __ArrayCustomQuickSort1D(ByRef $avArray, ByRef $sSortFunc, ByRef $iStart, ByRef $iEnd)
    ; Parameters ....: $avArray   - Array to sort
    ;                  $sSortFunc - Name of sorting function.
    ;                  $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.......: Erik Pilsits - removed IsNumber testing
    ; Remarks .......: For Internal Use Only
    ; Related .......:
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func __ArrayCustomQuickSort1D(ByRef $avArray, ByRef $sSortFunc, ByRef $iStart, ByRef $iEnd)
        If $iEnd <= $iStart Then Return
    
        Local $vTmp
    
        ; InsertionSort (faster for smaller segments)
        If ($iEnd - $iStart) < 15 Then
            Local $i, $j
            For $i = $iStart + 1 To $iEnd
                $vTmp = $avArray[$i]
                For $j = $i - 1 To $iStart Step -1
                    If (Call($sSortFunc, $vTmp, $avArray[$j]) >= 0) Then ExitLoop
                    $avArray[$j + 1] = $avArray[$j]
                Next
                $avArray[$j + 1] = $vTmp
            Next
            Return
        EndIf
    
        ; QuickSort
        Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)]
        Do
            While (Call($sSortFunc, $avArray[$L], $vPivot) < 0)
                $L += 1
            WEnd
            While (Call($sSortFunc, $avArray[$R], $vPivot) > 0)
                $R -= 1
            WEnd
    
            ; Swap
            If $L <= $R Then
                $vTmp = $avArray[$L]
                $avArray[$L] = $avArray[$R]
                $avArray[$R] = $vTmp
                $L += 1
                $R -= 1
            EndIf
        Until $L > $R
    
        __ArrayCustomQuickSort1D($avArray, $sSortFunc, $iStart, $R)
        __ArrayCustomQuickSort1D($avArray, $sSortFunc, $L, $iEnd)
    EndFunc   ;==>__ArrayCustomQuickSort1D
    
    ; #INTERNAL_USE_ONLY#============================================================================================================
    ; Name...........: __ArrayCustomQuickSort2D
    ; Description ...: Helper function for sorting 2D arrays
    ; Syntax.........: __ArrayCustomQuickSort2D(ByRef $avArray, ByRef $sSortFunc, 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.......: Erik Pilsits - removed IsNumber testing
    ; Remarks .......: For Internal Use Only
    ; Related .......:
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func __ArrayCustomQuickSort2D(ByRef $avArray, ByRef $sSortFunc, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax)
        If $iEnd <= $iStart Then Return
    
        ; QuickSort
        Local $i, $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)][$iSubItem]
        Do
            While ($iStep * Call($sSortFunc, $avArray[$L][$iSubItem], $vPivot) < 0)
                $L += 1
            WEnd
            While ($iStep * Call($sSortFunc, $avArray[$R][$iSubItem], $vPivot) > 0)
                $R -= 1
            WEnd
    
            ; 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
    
        __ArrayCustomQuickSort2D($avArray, $sSortFunc, $iStep, $iStart, $R, $iSubItem, $iSubMax)
        __ArrayCustomQuickSort2D($avArray, $sSortFunc, $iStep, $L, $iEnd, $iSubItem, $iSubMax)
    EndFunc   ;==>__ArrayCustomQuickSort2D