Jump to content
TheDcoder

Sorting a 2D array by version

Recommended Posts

TheDcoder

Hi, I have a 2D array with 2 columns, the 1st column contains a "version string" and the 2nd column contains a generic string. I want to sort it in the descending order so the latest version comes first.

#include <Array.au3>

Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]]

_ArraySort($aVersionsAndReleases, 1)
ConsoleWrite(_ArrayToString($aVersionsAndReleases, ' - '))
_ArrayDisplay($aVersionsAndReleases)

Unfortunately, _ArraySort isn't working here :(. This is the output generated by the script:

0.2.9.11 - Release #4
0.2.9.10 - Release #3
0.2.8.9 - Release #1
0.2.8.10 - Release #2

The expected result should be:

0.2.9.11 - Release #4
0.2.9.10 - Release #3
0.2.8.10 - Release #2
0.2.8.9 - Release #1

I am looking to develop an function which does this... but I don't know where to start :(. Can someone help me get started? Thanks in Advance! :D

- TD.


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
AspirinJunkie

I've written a sorting function for user defined sorting (see the UDF in attachment) .
With this the solution should be something like this:

#include "DynArray.au3"

Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]]

_ArraySortFlexible($aVersionsAndReleases, _MyCompare)
_ArrayDisplay($aVersionsAndReleases)


; user defined comparison function for user-defined sorting
Func _MyCompare(ByRef $A, ByRef $B)
    Local Static $h_DLL_Shlwapi = DllOpen("Shlwapi.dll")

    Return -DllCall($h_DLL_Shlwapi, "int", "StrCmpLogicalW", "wstr", $A[0], "wstr", $B[0])[0]
EndFunc   ;==>_MyCompare

 

DynArray.au3

Edited by AspirinJunkie
shorter comparison function
  • Like 1

Share this post


Link to post
Share on other sites
Jos

Here is an option with some good old fashioned programming logic:

#include <Array.au3>

Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]]

ReDim $aVersionsAndReleases[4][3]
For $x = 0 To UBound($aVersionsAndReleases) - 1
    $Version = StringSplit($aVersionsAndReleases[$x][0], ".")
    For $y = 1 To $Version[0]
        $aVersionsAndReleases[$x][2] &= StringRight("000000" & $Version[$y], 6)
    Next
Next
_ArraySort($aVersionsAndReleases, 1, 0, 0, 2)
ConsoleWrite(_ArrayToString($aVersionsAndReleases, ' - '))
_ArrayDisplay($aVersionsAndReleases)

Jos

  • Like 1

Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites
TheDcoder

@czardas I have looked into natural sort but most of them only talk about a single number... not multiple digits in a single column! I will look into them anyway. Now I know what natural sort is :D.

@Jos That's quick hack you have got there! :o. Never thought that it would be that simple :P:thumbsup:

@AspirinJunkie Your UDF looks very promising, I will give it a go :).

I will post back with the results which I finish playing around with the solutions. Thanks for post y'all! Much Appreciated! :D

  • Like 1

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
TheDcoder

In the end, I decided to go with @wraithdu's _ArrayNaturalSort. Just what I needed! :thumbsup:

#include <Array.au3>
#include <StringConstants.au3>

#Region Include Functions
; #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

; #FUNCTION# ====================================================================================================================
; Name...........: _NaturalCompare
; Description ...: Compare two strings using Natural (Alphabetical) sorting.
; Syntax.........: _NaturalCompare($s1, $s2[, $iCase = 0])
; Parameters ....: $s1, $s2 - Strings to compare
;                  $iCase   - [Optional] Case sensitive or insensitive comparison
;                  |0 - Case insensitive (default)
;                  |1 - Case sensitive
; Return values .: Success - One of the following:
;                  |0  - Strings are equal
;                  |-1 - $s1 comes before $s2
;                  |1  - $s1 goes after $s2
;                  Failure - Returns -2 and Sets @Error:
;                  |1 - $s1 or $s2 is not a string
;                  |2 - $iCase is invalid
; Author ........: Erik Pilsits
; Modified.......:
; Remarks .......: Original algorithm by Dave Koelle
; Related .......: StringCompare
; Link ..........: http://www.davekoelle.com/alphanum.html
; Example .......: Yes
; ===============================================================================================================================
Func _NaturalCompare($s1, $s2, $iCase = 0)
    ; check params
    If (Not IsString($s1)) Then $s1 = String($s1)
    If (Not IsString($s2)) Then $s2 = String($s2)
    ; check case, set default
    If $iCase <> 0 And $iCase <> 1 Then $iCase = 0

    Local $n = 0
    Local $s1chunk, $s2chunk
    Local $idx, $i1chunk, $i2chunk
    Local $s1temp, $s2temp

    While $n = 0
        ; get next chunk
        ; STRING 1
        $s1chunk = StringRegExp($s1, "^(\d+|\D+)", 1)
        If @error Then
            $s1chunk = ""
        Else
            $s1chunk = $s1chunk[0]
        EndIf
        ; STRING 2
        $s2chunk = StringRegExp($s2, "^(\d+|\D+)", 1)
        If @error Then
            $s2chunk = ""
        Else
            $s2chunk = $s2chunk[0]
        EndIf

        ; ran out of chunks, strings are the same, return 0
        If $s1chunk = "" And $s2chunk = "" Then Return 0

        ; remove chunks from strings
        $s1 = StringMid($s1, StringLen($s1chunk) + 1)
        $s2 = StringMid($s2, StringLen($s2chunk) + 1)

        Select
            ; Case 1: both chunks contain letters
            Case (Not StringIsDigit($s1chunk)) And (Not StringIsDigit($s2chunk))
                $n = StringCompare($s1chunk, $s2chunk, $iCase)
            ; Case 2: both chunks contain numbers
            Case StringIsDigit($s1chunk) And StringIsDigit($s2chunk)
                ; strip leading 0's
                $s1temp = $s1chunk
                $s2temp = $s2chunk
                $s1chunk = StringRegExpReplace($s1chunk, "^0*", "")
                $s2chunk = StringRegExpReplace($s2chunk, "^0*", "")
                ; record number of stripped 0's
                $s1temp = StringLen($s1temp) - StringLen($s1chunk)
                $s2temp = StringLen($s2temp) - StringLen($s2chunk)
                ; first check if one string is longer than the other, meaning a bigger number
                If StringLen($s1chunk) > StringLen($s2chunk) Then
                    Return 1
                ElseIf StringLen($s1chunk) < StringLen($s2chunk) Then
                    Return -1
                EndIf
                ; strings are equal length
                ; compare 8 digits at a time, starting from the left, to avoid overflow
                $idx = 1
                While 1
                    $i1chunk = Int(StringMid($s1chunk, $idx, 8))
                    $i2chunk = Int(StringMid($s2chunk, $idx, 8))
                    ; check for end of string
                    If $i1chunk = "" And $i2chunk = "" Then
                        ; check number of leading 0's removed, if any - windows sorts more leading 0's above fewer leading 0's, ie 00001 < 0001 < 001
                        If $s1temp > $s2temp Then
                            Return -1
                        ElseIf $s1temp < $s2temp Then
                            Return 1
                        Else
                            ; numbers are equal
                            ExitLoop
                        EndIf
                    EndIf
                    ; valid numbers, so compare
                    If $i1chunk > $i2chunk Then
                        Return 1
                    ElseIf $i1chunk < $i2chunk Then
                        Return -1
                    EndIf
                    ; chunks are equal, get next chunk of digits
                    $idx += 8
                WEnd
            ; Case 3: one chunk has letters, the other has numbers; or one is empty
            Case Else
                ; if we get here, this should be the last and deciding test, so return the result
                Return StringCompare($s1chunk, $s2chunk, $iCase)
        EndSelect
    WEnd

    Return $n
EndFunc

; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayNaturalSort
; Description ...: Sort a 1D or 2D array on a specific index using the quicksort/insertionsort algorithms.
; Syntax.........: _ArrayNaturalSort(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
;                  |5 - Invalid sort function
; Author ........: Erik Pilsits
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........: https://www.autoitscript.com/forum/topic/83626-natural-order-string-comparison/
; Example .......: No
; ===============================================================================================================================
Func _ArrayNaturalSort(ByRef $avArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0)
    Return _ArrayCustomSort($avArray, "_NaturalCompare", $iDescending, $iStart, $iEnd, $iSubItem)
EndFunc   ;==>_ArrayNaturalSort
#EndRegion

Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]]

_ArrayNaturalSort($aVersionsAndReleases, 1)
ConsoleWrite(_ArrayToString($aVersionsAndReleases, ' - '))
_ArrayDisplay($aVersionsAndReleases)

 

Edited by TheDcoder
Forgot to add the link to wraithdu's thread

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
mikell

A variant of Jos version, mucho classic too  :)

Local $aVersionsAndReleases[5][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"], ["0.3", "Release #3"]]

ReDim $aVersionsAndReleases[5][3]
For $x = 0 To UBound($aVersionsAndReleases) - 1
    $Version = StringSplit($aVersionsAndReleases[$x][0], ".")
    For $y = 1 To $Version[0]
        $aVersionsAndReleases[$x][2] &= StringFormat("%03i", $Version[$y])
    Next
Next
_ArraySort($aVersionsAndReleases, 1, 0, 0, 2)
ConsoleWrite(_ArrayToString($aVersionsAndReleases, ' - '))
_ArrayDisplay($aVersionsAndReleases)

 

Share this post


Link to post
Share on other sites
czardas

Natural sort is more flexible however, for a bespoke situation such as this, it could be considered overkill. I tend to strip away things I don't need once everything is working, so I quite often use a standard function with all the bells and whistles attached before making final adjustments. This approach can sometimes be useful when you are unsure of all the features you intend to implement: eventually you might want to keep the whistles and get rid of the bells. I don't think there is a right or wrong approach to this and the methods above are all valid. :)

Edited by czardas
  • Like 1

Share this post


Link to post
Share on other sites
TheDcoder

Well said @czardas :D.

  • Like 1

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
Malkey

This method converts a[.b[.c[.d]]]] to 00a[00b[00c[00d]]]] (Where abcd are digits.) by executing a string from a StringRegExpReplace function.

It works on a 1D or 2D array.

#include <Array.au3>

Local $aVersionsAndReleases[6][2] = [["0.2.8.9", "Release #2"], ["0.2.9.10", "Release #1"], ["0.2.8", "Release #1"], _
                                     ["0.2.7.10", "Release #1"], ["0.2.9.11", "Release #2"], ["0.3", "Release #1"]]
; Or try
;Local $aVersionsAndReleases[6] = ["0.2.8.9", "0.2.9.10", "0.2.8", "0.2.7.10", "0.2.9.11", "0.3"] ; 1D array

_ArrayColInsert($aVersionsAndReleases, 0) ; Add a new column, Col 0.
For $x = 0 To UBound($aVersionsAndReleases) - 1
    $aVersionsAndReleases[$x][0] = Execute(StringTrimRight(StringRegExpReplace($aVersionsAndReleases[$x][1], "(\d+)\.?", _
              'StringRight("000${1}", 3) & '), 3)) ; Converts a[.b[.c[.d]]]] to 00a[00b[00c[00d]]]] Where abcd are digits.
    ;ConsoleWrite(StringRegExpReplace($aVersionsAndReleases[$x][1], "(\d+)\.?", 'StringRight("000${1}", 3) & ') & @CRLF)
Next
_ArraySort($aVersionsAndReleases, 1, 0, 0, 0)
ConsoleWrite(_ArrayToString($aVersionsAndReleases, ' - '))
_ArrayColDelete($aVersionsAndReleases, 0, True) ; Now delete the added column.
_ArrayDisplay($aVersionsAndReleases)

 

  • Like 2

Share this post


Link to post
Share on other sites
TheDcoder

More RegEx magic. Thanks for the code @Malkey :)


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
iamtheky

edit: super late as per usual

I ended up with the Jos/Malkey answer as well, but with no want to fix the formatting after altered.

#include <Array.au3>

Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]]

for $i = 0 to ubound($aVersionsAndReleases) - 1
    $aSplit = stringsplit($aVersionsAndReleases[$i][0] , "." , 2)
    $aSplit[ubound($aSplit) - 1] = StringFormat("%02i" , $aSplit[ubound($aSplit) - 1])
    $aVersionsAndReleases[$i][0] = _ArrayToString($aSplit , ".")
next

_ArraySort($aVersionsAndReleases, 1)
_ArrayDisplay($aVersionsAndReleases)

 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
TheDcoder
4 minutes ago, iamtheky said:

but with no want to fix the formatting after altered.

I needed a solution which fixes the version string after the sorting because those version numbers are displayed to the user and I do not want the user get confused! Albeit, it is a nice way if you want to sort the array internally :)


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
iamtheky

nah, its probably slower than the regexp if you are going to send it through formatting a second time.  

I havent seen a good race thread in a while, version sort could stand to go through the wringer.

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
Chimp

I had a similar case here :

using the regexp provided on post # 7 of that topic, here's another shot:

#include <array.au3>
Local $aVersionsAndReleases[][] = [["0.2.8.9", "Release #1"],["0.2.9.10", "Release #3"],["0.2.9.11", "Release #4"],["0.2.8.10", "Release #2"],["0.3", "Release #5"]]
;
For $i = 0 To UBound($aVersionsAndReleases) - 1
    $aVersionsAndReleases[$i][0] = StringRegExpReplace($aVersionsAndReleases[$i][0], '(?<!\d)(\d)(?!\d)', '0\1')
Next
;
_ArraySort($aVersionsAndReleases, 1, 0, 0, 0)
_ArrayDisplay($aVersionsAndReleases)

 


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
TheDcoder

RegEx for the rescue again, thanks for sharing the code :)


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
iamtheky

*Fixed in post #19

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
AspirinJunkie

@iamthekey

try with this values:

Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.1", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]]

 

  • Like 1

Share this post


Link to post
Share on other sites
iamtheky

my bad, somehow removed the type 2s (to remove the ubound count) from my stringsplits

#include <Array.au3>

Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.1", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]]

_ArraySort($aVersionsAndReleases, 1)

for $i = 1 to ubound($aVersionsAndReleases) - 1


If StringSplit($aVersionsAndReleases[$i][0] , "." , 2)[0] = StringSplit($aVersionsAndReleases[$i - 1][0] , "." , 2)[0] AND StringSplit($aVersionsAndReleases[$i][0] , "." , 2)[1] = StringSplit($aVersionsAndReleases[$i - 1][0] , "." , 2)[1] AND StringSplit($aVersionsAndReleases[$i][0] , "." , 2)[2] = StringSplit($aVersionsAndReleases[$i - 1][0] , "." , 2)[2] AND execute(StringReplace($aVersionsAndReleases[$i][0] , "." , "+")) > execute(StringReplace($aVersionsAndReleases[$i - 1][0] , "." , "+")) Then _ArraySwap($aVersionsAndReleases , $i , $i - 1)


next

_ArrayDisplay($aVersionsAndReleases)

 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
Malkey

 @iamtheky

Try with this array in your example of post #19.

Local $aVersionsAndReleases[4][2] = [["0.2.9.4", "Release #1"], ["0.2.9.21", "Release #4"], ["0.2.9.11", "Release #3"], ["0.2.9.5", "Release #2"]]

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • VollachR
      By VollachR
      Hi,
      I'm looking for a way to take a number value from a Row2 of a 2D array and according to this check if files that appear in rows 3-11 in the array exists.
      For example, if the number in Row2 is 5 I need to check for the files in Row 3-6 only, if it is 6 than rows 3-7 and so on.
      I thought on using a FOR loop but I have very little experience with those.
      Can you suggest the best way to do what I need?
      BTW, the files in Rows 3-11 will usually have blank value for any row above the number in Row2 (e.g. Row2 = 5 so Rows3-6 will have values but 8-11 be empty), The values I need are in Column 1 of the array, the name of the key from the INI file that the array was created from is in Column 0.
      Full Example:
      Row2 of Array:
      Col0 = Games# - Col1 = 5
      Rows3-6
      Col0 = Exe2 - Col1 = Path To File
      Col0 = Exe3 - Col1 = Path To File
      Col0 = Exe4 - Col1 = Path To File
      Col0 = Exe5 - Col1 = Path To File
      I need that if Row2 is 5 to check these above for rows if the file exists, if it was 6 then the next row as well and so on up until number 10 in Row2 as it can't go above 10.
      So basically for whatever number in Row2 from 2-10 need to check 1-9 rows from 3-11 to see if the files in Col1 exists and if any of them don't exist it should call a function that shows an error message.
      I'm pretty sure I have the first line of the for look correct:
      For $i = 1 To $aAIO[2][1] Just not sure how to continue from there, also not sure if $i should be equal 1 or 2.
      Help will be appreciated.
    • TimRude
      By TimRude
      The help text for the _ArrayDisplay function says: "Clicking on a column header sort it."
      I'm wondering why the sorting of hex numbers (specifically window handles like 0x12345678) is so wonky.
      Sample script:
      #include <Array.au3> Local $aList = WinList() _ArrayDisplay($aList) Clicking on the Col1 header to sort by window handle doesn't properly sort the list.
      As a workaround, I'm sorting the array by window handle before displaying it using _ArraySort. But I still wonder what's up with the ListView sorting.
      Workaround:
      #include <Array.au3> Local $aList = WinList() _ArraySort($aList, 0, 1, 0, 1) _ArrayDisplay($aList)  
    • FMS
      By FMS
      Hello,
      I'm trying to get data from twitter to an array and so far I found an Twitter UDF whish lookes very intresting but couldn't get it to work.
      It lookes not supported any more(2010) and buggy when i read all te replies.
      More around this subject (autoit and twitter) i couldn't find on this forum.
      Is there sombody who know's a good way to get live data from twitter to an array inside autoit?
      (I kinda doubt that this isn't tackled before)
      In the end I was hoping to get all tweets from date to date from an specific subject inside a 2D array to work whit.
    • AndreasNWWWWW
      By AndreasNWWWWW
      I got a question:  i am trying to run different functions based upon what i select in these radio buttons.(code below)
      it needs to check server 1. then run function 1 or function 2 after what i selected in the checkbox.
      once that function is done it moves to the next one, until it has been trough all 5 
       
      iv'e tried using while loops with different while $i equals to something but then i manualy need to go in and edit the script every time.
      #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 615, 437, 192, 124) $Server2 = GUICtrlCreateLabel("Server2", 216, 95, 41, 17) $server1 = GUICtrlCreateLabel("Server1", 216, 72, 41, 17) $server4 = GUICtrlCreateLabel("Server4", 216, 144, 41, 17) $server3 = GUICtrlCreateLabel("Server3", 216, 119, 41, 17) $server5 = GUICtrlCreateLabel("Server5", 216, 170, 41, 17) $Start = GUICtrlCreateButton("Start", 240, 248, 147, 25) $Checkbox1 = GUICtrlCreateCheckbox("function1", 288, 72, 97, 17) $Checkbox2 = GUICtrlCreateCheckbox("function2", 392, 72, 97, 17) $Checkbox3 = GUICtrlCreateCheckbox("function1", 288, 96, 97, 17) $Checkbox4 = GUICtrlCreateCheckbox("function2", 392, 96, 97, 17) $Checkbox5 = GUICtrlCreateCheckbox("function1", 288, 120, 97, 17) $Checkbox6 = GUICtrlCreateCheckbox("function2", 392, 120, 97, 17) $Checkbox7 = GUICtrlCreateCheckbox("function1", 288, 144, 97, 17) $Checkbox8 = GUICtrlCreateCheckbox("function2", 392, 144, 97, 17) $Checkbox9 = GUICtrlCreateCheckbox("function1", 288, 170, 97, 17) $Checkbox10 = GUICtrlCreateCheckbox("function2", 392, 170, 97, 17) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd  
    • 31290
      By 31290
      Hi everyone, 
      I'm currently writing a script that allow me to list all currently installed software on a computer but some of the are listed in the HKLM64 hive of the registry whereas 95% of all others are in the HKLM "normal" one.
      Thing is, I'd like to combine these two reg key into one single ListView item.
      Here's my code so far, knowing that it's working on both cases (changing to HKLM64 or HKLM short)
      Thanks in advance for the help
      -31290-
×