Jump to content

Sorting version numbers


Recommended Posts

  • Moderators

If i have an array that contains for example:

> 1.4.6.124

> 0.5.24.195

> 1.3.12.1

> 0.55.6.9

How would i go about finding which is the highest? =S

Are these versions?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

This might be better... I tested it a little bit... maybe someone can confirm that this is really working like I think it is:

Func _VersionCompare($sOne, $sTwo)
    Local $nCompare = StringCompare($sOne, $sTwo)
    If $nCompare = 0 Then Return 0;Versions are equal
    If $nCompare > 0 Then Return 1;$sOne is greater
    Return -1;$sTwo is greater
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

It appears work okay as long as the numbers aren't padded with zeroes.

Can you give me an example? I'd match rather use a mathematical way rather than doing it the old way.

Padded... (Only one example):

$a = "2.4.5"
$b = "2.03.05.07"
MsgBox(0, '', _FileCompareVersions($a, $B))
Func _FileCompareVersions($sVersion1, $sVersion2)
    Local $nCompare = StringCompare($sVersion1, $sVersion2)
    If $nCompare = 0 Then Return $sVersion1
    If $nCompare > 0 Then Return $sVersion1
    Return $sVersion2
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

This returns 1 even though they are technically the same in terms of quantity.

MsgBox(0,"",_VersionCompare("3.2.8.1", "3.2.08.1"))

Func _VersionCompare($sOne, $sTwo)
    Local $nCompare = StringCompare($sOne, $sTwo)
    If $nCompare = 0 Then Return 0;Versions are equal
    If $nCompare > 0 Then Return 1;$sOne is greater
    Return -1;$sTwo is greater
EndFunc
Edited by weaponx
Link to comment
Share on other sites

Can you give me an example? I'd match rather use a mathematical way rather than doing it the old way.

Padded... (Only one example):

$a = "2.4.5"
$b = "2.03.05.07"
MsgBox(0, '', _FileCompareVersions($a, $B))
Func _FileCompareVersions($sVersion1, $sVersion2)
    Local $nCompare = StringCompare($sVersion1, $sVersion2)
    If $nCompare = 0 Then Return $sVersion1
    If $nCompare > 0 Then Return $sVersion1
    Return $sVersion2
EndFuncoÝ÷ Ûú®¢×v÷öÛay/"¢yî·«r©j·¬q©ÛzfzØZ¶È¦¦W*.znµ©Z®«éz¼"^iا7«¢+_j)ljëh×6$a = "2.4.5"
$b = "2.05.05.07"

May just because it doesn't account for missing parts (one has three parts the other four).

I wrote one a while back to check current driver version against available update driver version, and did it the long way: split each part, pad with trailing zeros so both have the same number of parts, convert to numeric by multiplying each part by 1G, 1M, 1K, 1, and assemble it into a number then do straight numeric compare. You can even have a trailing numeric if you convert that like a=0.1, D=0.4, ad=0.001004. Not short and tight, but very reliable that way.

So 2.4.5 = 2004005000, and 2.03.05.7ad = 2003005007.001004 for the compare.

Don't have the function here, and no time to recode it at the moment so I can't show the demo right now.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I threw this together, it's pretty sweet:

;Return Values
;0 string1 and string2 are equal 
;> 0 (1) string1 is greater than string2 
;< 0 (-1) string1 is less than string2 

;Not required, only used for testing
#include <Array.au3>

MsgBox(0,"",_VersionCompare2("3.2.8", "3.2.8.0")) ;Same
MsgBox(0,"",_VersionCompare2("3.2.8.1", "3.2.8.3")) ; String 2 is greater
MsgBox(0,"",_VersionCompare2("5", "3.2.8.3")) ; String 1 is greater

Func _VersionCompare2($sOne, $sTwo)
    ;Set default return value to same
    Dim $returnValue = 0
    
    Dim $arrayOne[4] = [0,0,0,0]
    Dim $arrayTwo[4] = [0,0,0,0]
    
    $tempOne = StringSplit($sOne, ".")
    $tempTwo = StringSplit($sTwo, ".")
    
    ;Copy anything available from first input version
    For $X = 1 to $tempOne[0]
        If $X > 4 Then ExitLoop
        $arrayOne[$X - 1] = Number($tempOne[$X])
    Next
    
    ;Copy anything available from second input version
    For $X = 1 to $tempTwo[0]
        If $X > 4 Then ExitLoop
        $arrayTwo[$X - 1] = Number($tempTwo[$X])
    Next
    
    ;Compare each individual element instead of whole string
    For $X = 0 to 3
        ;MsgBox(0,"",StringCompare ($arrayTwo[$X],$arrayTwo[$X]))
        Switch StringCompare ($arrayOne[$X],$arrayTwo[$X])
            Case 0
                $returnValue = 0
            Case -1
                $returnValue = -1
                ExitLoop
            Case 1
                $returnValue = 1
                ExitLoop
        EndSwitch
    Next
    
    ;_ArrayDisplay($arrayOne)
    ;_ArrayDisplay($arrayTwo)
    
    Return $returnValue
EndFunc
Link to comment
Share on other sites

  • Moderators

I threw this together, it's pretty sweet:

;Return Values
;0 string1 and string2 are equal 
;> 0 (1) string1 is greater than string2 
;< 0 (-1) string1 is less than string2 

;Not required, only used for testing
#include <Array.au3>

MsgBox(0,"",_VersionCompare2("3.2.8", "3.2.8.0")) ;Same
MsgBox(0,"",_VersionCompare2("3.2.8.1", "3.2.8.3")) ; String 2 is greater
MsgBox(0,"",_VersionCompare2("5", "3.2.8.3")) ; String 1 is greater

Func _VersionCompare2($sOne, $sTwo)
    ;Set default return value to same
    Dim $returnValue = 0
    
    Dim $arrayOne[4] = [0,0,0,0]
    Dim $arrayTwo[4] = [0,0,0,0]
    
    $tempOne = StringSplit($sOne, ".")
    $tempTwo = StringSplit($sTwo, ".")
    
    ;Copy anything available from first input version
    For $X = 1 to $tempOne[0]
        If $X > 4 Then ExitLoop
        $arrayOne[$X - 1] = Number($tempOne[$X])
    Next
    
    ;Copy anything available from second input version
    For $X = 1 to $tempTwo[0]
        If $X > 4 Then ExitLoop
        $arrayTwo[$X - 1] = Number($tempTwo[$X])
    Next
    
    ;Compare each individual element instead of whole string
    For $X = 0 to 3
        ;MsgBox(0,"",StringCompare ($arrayTwo[$X],$arrayTwo[$X]))
        Switch StringCompare ($arrayOne[$X],$arrayTwo[$X])
            Case 0
                $returnValue = 0
            Case -1
                $returnValue = -1
                ExitLoop
            Case 1
                $returnValue = 1
                ExitLoop
        EndSwitch
    Next
    
    ;_ArrayDisplay($arrayOne)
    ;_ArrayDisplay($arrayTwo)
    
    Return $returnValue
EndFunc
Ha! I just saw this... Good job.

Something that might make it easier is just to return the version number that is requested (ie... make a param... $nNewest = 1) > 0 being newest returned string, anything else oldest.

Edit:

Ut Oh :)

Run this:

MsgBox(0,"",_VersionCompare2("3.2.8.2a", "3.2.8.2b")) ; String 2 is greater

Return Value is 0

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Here try this one...

MsgBox(0,"",_VersionCompare2("3.2.8", "3.2.8.0")) ;Same
MsgBox(0,"",_VersionCompare2("3.2.8.2c", "3.2.8.2b")) ; String 2 is greater
MsgBox(0,"",_VersionCompare2("5", "3.2.8.3")) ; String 1 is greater

Func _VersionCompare2($sOne, $sTwo, $nNewer = 1)
    ;Set default return value to same
    Local $returnValue = 0, $nCompare
    Local $arrayOne[4] = [0,0,0,0], $arrayTwo[4] = [0,0,0,0]
   
    Local $tempOne = StringSplit($sOne, "."), $tempTwo = StringSplit($sTwo, ".")
   
    ;Copy anything available from first input version
    For $X = 1 to $tempOne[0]
        If $X > 4 Then ExitLoop
        $arrayOne[$X - 1] = $tempOne[$X]
    Next
   
    ;Copy anything available from second input version
    For $X = 1 to $tempTwo[0]
        If $X > 4 Then ExitLoop
        $arrayTwo[$X - 1] = $tempTwo[$X]
    Next
    ;Compare each individual element instead of whole string
    For $X = 0 to 3
        ;MsgBox(0,"",StringCompare ($arrayTwo[$X],$arrayTwo[$X]))
        Switch StringCompare ($arrayOne[$X],$arrayTwo[$X])
            Case 0
                $returnValue = 0
            Case -1
                $returnValue = -1
                ExitLoop
            Case 1
                $returnValue = 1
                ExitLoop
        EndSwitch
    Next
    If $nNewer Then
        If $returnValue > -1 Then Return $sOne
        Return $sTwo
    EndIf
    If $returnValue > -1 Then Return $sOne
    Return $sTwo
EndFunc
Should allow for all chars now.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Hey we were talking about version numbers, not version letters!

I see you removed the Number() function. I think I added that because it would strip off any leading zeros to make the comparison more consistent. Also as far as the return values are concerned I stuck with the StringCompare return values because it's easier to run a case statement or if statement against.

Edited by weaponx
Link to comment
Share on other sites

  • Moderators

Hey we were talking about version numbers, not version letters!

I see you removed the Number() function. I think I added that because it would strip off any leading zeros to make the comparison more consistent. Also as far as the return values are concerned I stuck with the StringCompare return values because it's easier to run a case statement or if statement against.

Yeah, I see now the leading zero being an issue again... I have versions of my own apps that have numbers/letters so that's why I thought of it above.

I guess we could just do a regular expression... I'd have to give it some thought... but right now I'm working on 30 hours straight, and not thinking quite clearly, so I could end up making something that reformats your PC for you instead... It will have to wait on my end at least (but I know you're already on it :) )

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Well now that we have thoroughly hijacked this thread...

This version will allow alphanumeric and doesn't restrict to a max of 4 octets. Enjoy.

; Title: VersionCompareX
; Author: WeaponX

;Return Values
;0 string1 and string2 are equal
;1 string1 is greater than string2
;-1 string1 is less than string2

;Compare version numbers with differing lengths
MsgBox(0,"",_VersionCompareX("3.2.8", "3.2.8.0")) ;Same (return 0)

;Straight compare
MsgBox(0,"",_VersionCompareX("3.2.8.1", "3.2.8.3")) ; String 2 is greater (return -1)

;Compare against single digit
MsgBox(0,"",_VersionCompareX("5", "3.2.8.3")) ; String 1 is greater (return 1)

;Compare alphanumeric
MsgBox(0,"",_VersionCompareX("3.2.8.3", "3.2.8.3a")) ; String 2 is greater (return -1)

;Compare version numbers with extreme lengths
MsgBox(0,"",_VersionCompareX("3", "3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0")) ; Same (return 0)

;Compare version numbers with extreme lengths & alpha
MsgBox(0,"",_VersionCompareX("3", "3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a")) ; String 2 is greater (return -1)


Func _VersionCompareX($sOne, $sTwo)
    ;Set default return value to same
    Local $returnValue = 0
   
    Local $tempOne = StringSplit($sOne, "."), $tempTwo = StringSplit($sTwo, ".")
    
    ;Determine number of positions to compare against
    Local $numPositions = $tempOne[0]
    If $tempTwo[0] > $tempOne[0] Then $numPositions = $tempTwo[0]
    
    ;Declare temp arrays
    Dim $arrayOne[$numPositions], $arrayTwo[$numPositions]
    
    ;Fill temp arrays with zeros
    For $X = 0 to $numPositions - 1
        $arrayOne[$X] = 0
        $arrayTwo[$X] = 0
    Next
   
    ;Copy anything available from first input version
    For $X = 1 to $tempOne[0]
        If $X > $numPositions Then ExitLoop
        
        ;Strip leading zeroes
        $stripped = StringRegExpReplace ($tempOne[$X], "^0+", "")
       
        If $stripped <> "" Then $arrayOne[$X - 1] = $stripped
    Next
   
    ;Copy anything available from second input version
    For $X = 1 to $tempTwo[0]
        If $X > $numPositions Then ExitLoop
        
        ;Strip leading zeroes
        $stripped = StringRegExpReplace ($tempTwo[$X], "^0+", "")
        
        If $stripped <> "" Then $arrayTwo[$X - 1] = $stripped      
    Next
   
    ;Compare each individual element instead of whole string
    For $X = 0 to $numPositions - 1
        Switch StringCompare ($arrayOne[$X],$arrayTwo[$X])
            Case 0
                $returnValue = 0
            Case -1
                $returnValue = -1
                ExitLoop
            Case 1
                $returnValue = 1
                ExitLoop
        EndSwitch
    Next
   
    Return $returnValue
EndFunc
Edited by weaponx
Link to comment
Share on other sites

  • 9 years later...

Sorry to bump this old thread but I found a bug in it =)

 

MsgBox(0,"",_VersionCompareX("15.17.0.1", "3.0.0.34")) ; String 1 is greater (return 1)

 

It actually returns -1 as if string 2 is greater.

 

Using _VersionCompare works fine though.

#include <Misc.au3>
ConsoleWrite(_VersionCompare ( "15.17.0.1", "3.0.0.34" ) & @CRLF)

1

Edited by Turranius
Link to comment
Share on other sites

Better idea is to create a new thread and add a link to this thread.
You will get much more attention!

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...