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

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

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

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     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

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

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

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

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
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

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

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

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

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

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

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

    • Skeletor
      By Skeletor
      Hi Virtual People,
      My array works perfectly fine. However, what is the best practice if the line in the array doesn't have the correct amount of columns and if I can add a placeholder?

       
      For $count = 1 To _FileCountLines($FileRead1) Step 1 $string = FileReadLine($FileRead1, $count) $input = StringSplit($string, ",", 1) $value1 = $input[1] $value2 = $input[2] $value3 = $input[3] _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $value2, "A1") _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $value1, "B1") _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $value3, "C1") Next  
    • MrCheese
      By MrCheese
      hi all,
      reviewing the forum, this thread is applicable: 
       
       
      I wanted to know if there is now a better way to do this?
      In essence, I load a tab delimited txt file into an array (works well). I used tab, as some fields in the original csv contains commas.
      However, I needed autoit to manipulate this array, and output it as a csv.
      IF my array contains items with a comma, without double quotes around the field, then how best do I get a csv out of this?
      My current workaround is to filewritefromarray tab delimited, then open it in excel and save as a csv. I will need to check this to see how the address fields behave that contain a comma.
       
      Any thoughts would be appreciated.
       
    • Skeletor
      By Skeletor
      Hi All,

      I would like to know how you would take a FileLineRead and insert it into an array which then inserts it into Excel?
      One thing to know is the files content is broken up, so I only use half of the content within $FileRead1.
      So its imperative that the $value1, $value2, etc variables be used. 
      Code below:
      $FileRead1 = FileReadLine("C:\temp\sample.txt",1) For $count = 1 To _FileCountLines($FileRead1) Step 1 $string = FileReadLine($FileRead1, $count) $input = StringSplit($string, ",", 1) $value1 = $input[1] $value2 = $input[2] $value3 = $input[3] $value4 = $input[4] _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $value1, "A1") _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $value2, "B1") _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $value3, "C1") _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $value4, "D1") Next  
    • AnonymousX
      By AnonymousX
      Hello,
      I'm trying to write a script that moves copies excel cells into an array. I'll than manipulate the values and send array into another program. 
      I don't want range to be specific to a workbook, or sheet, or set of cells.
      I want user to be able to highlight desired cells and to copy either normally ("Ctrl+C") or by a hotkey ("Alt+C"). 
      Could someone help me with this?
      Thank you,
      I've tried to write the framework: (edited)
      #include <MsgBoxConstants.au3> #include <Array.au3> #include <Excel.au3> HotKeySet("!v", "Pastedata") While True Sleep(1000) WEnd func Makearray() local $bArray ;User has cells already copied ;Convert clipboard into an array ;I don;t know how excel stores data to clipboard so don;t know how to bring it into array _Arraydisplay($bArray) MsgBox(0,0,$bArray) return $bArray endfunc func Pastedata() Local $aArray MsgBox(0,0,"wait",1) ;make array based on assumption user has already copied a range to clipboard $aArray = Makearray() ;paste code ;don;t worry about this I got the rest endfunc  
    • Dzenan03
      By Dzenan03
      I want to make a while loop, that creates variables based on a array. For thist I created the array $iDsO with the number and the name of folders in an other folder. Every folder has a different name an I want to create variables(arrays) for each folder that show me all the files in that folder. For example: I have the Folder \Folder1. In it there are the Folders \1, \2, \3. In 1, 2 and 3 there are some files(.png). The array for Folder1 is $iDsO and now I want to crate the arrays $iDsO1, $iDsO2 and $iDsO3 with the files in them can I make something like this:
      While $iDs > 0 ;$iDs is the number of files in Folder1>> $iDsO[0] $iDs#here should come the Foldername for example '1'# = _FileListtoArray(@ProgramFilesDir&"\Folder1\"&$iDsO[$iDs]) $iDs = $iDs - 1 Wend So that in the End I have three variabels ($iDs1, $iDs2 and $iDs3)
       
      Is this posible or if not what could I do instead ( I don´t know the number of folders in Folder1 in the begining).
×