locked
Compare object unable to compare versions RRS feed

  • Question

  • $dev=@(2.2.3, 2.3.4, 2.5.6) $qa=@(1.1.1, 2.2.7) In above I want [bool]$match=$false $match = compare [version]$dev,[version]$qa If any of element in $qa is > $dev (comparing all versions of dev) then $match is $true,

    I am unable to compare array of versions using compare object



    Friday, February 28, 2020 6:55 PM

Answers

  • To compare version number just compare them as versions.

    [version]$qa[0]  -gt [version]$dev[0]

    This is the only way to do this that makes any sense or that will work technically.

    To do this against an array it is best to create an array of versions.

    $dev=@(
        [version]'2.2.3',
        [version]'2.3.4',
        [version]'2.5.6'
    )
    $qa=@(
        [version]'1.1.1',
        [version]'2.2.7'
    )
    foreach($q in $qa){
        if($dev | %{$q -gt $_}|where{$_}){
            $q
        }
    }

    Note that version numbers are not numeric,  They are strings with a specific format.  You cannot use a double dotted number in PowerShell.  It will just be seen as a null.

    Try this to see what I mean:

    $x = 1.2.3
    $x


    \_(ツ)_/

    Friday, February 28, 2020 7:17 PM

All replies

  • To compare version number just compare them as versions.

    [version]$qa[0]  -gt [version]$dev[0]

    This is the only way to do this that makes any sense or that will work technically.

    To do this against an array it is best to create an array of versions.

    $dev=@(
        [version]'2.2.3',
        [version]'2.3.4',
        [version]'2.5.6'
    )
    $qa=@(
        [version]'1.1.1',
        [version]'2.2.7'
    )
    foreach($q in $qa){
        if($dev | %{$q -gt $_}|where{$_}){
            $q
        }
    }

    Note that version numbers are not numeric,  They are strings with a specific format.  You cannot use a double dotted number in PowerShell.  It will just be seen as a null.

    Try this to see what I mean:

    $x = 1.2.3
    $x


    \_(ツ)_/

    Friday, February 28, 2020 7:17 PM
  • In addition to what JRV points out, in your example you're trying to cast the arrays $dev and $qa as System.Version types. That doesn't work:

      Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Version"


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Friday, February 28, 2020 8:38 PM
  • But you can cast it this way:

    $dev = [version[]]@('2.2.3','2.3.4','2.5.6')


    \_(ツ)_/

    Friday, February 28, 2020 9:25 PM
  • I want to use compare object only, using foreach I was done it but due to no of versions are more also I have not only extract common app versions but system versions too like dotnetcore runtime and dotnet sdks, I want to use one liner compare object, is it possible with compare object

    $dev=$dev|%{[System.Version]$_}|sort
    $qa=$qa|%{[System.Version]$_}|sort
    
    Compare $dev, (if($qa | %{$_ -gt $_.referenceobject}|where{$_}){ $q}) 
    Similar to this

    Saturday, February 29, 2020 5:28 AM
  • I want to use compare object only, using foreach I was done it but due to no of versions are more also I have not only extract common app versions but system versions too like dotnetcore runtime and dotnet sdks, I want to use one liner compare object, is it possible with compare object

    $dev=$dev|%{[System.Version]$_}|sort
    $qa=$qa|%{[System.Version]$_}|sort
    
    Compare $dev, (if($qa | %{$_ -gt $_.referenceobject}|where{$_}){ $q}) 
    Similar to this

    I think you don't understand the different between the concept of "compare" and "greater than".  They are not even similar concepts.

    "Versions" are not numbers.  They are also not objects in the sense that they can be compared the way you are thinking.  "Compare-Object" comapr5es the members of a collection for existence between two collections.  

    Take some time to think about what you are asking.  It would also help if you first learned PowerShell before trying to ask questions.  Without some understanding of basic logic and programming understanding this might be difficult.  Learning PowerShell will help you to acquire these skills.


    \_(ツ)_/

    Saturday, February 29, 2020 12:15 PM
  • If, for some reason, this is a critical need, then you can use the "CompareTo" method of the Net Framework "array" base class to create a custom comparer.  Here is an exampe:

    https://docs.microsoft.com/en-us/dotnet/api/system.collections.istructuralcomparable?view=netframework-4.8

    This will show you how to create a custom comparer to compare an array with an element.  It is much easier to do it the way I posted.

    You could also use Linq methods to the answer to you issue.

    Part of the issue is that you are asking a very complex question that asks to enumerate two collection and detect a specific condition.  Even in C# or C++ there is no way to do this in one line.

    Also you need to realize the the "compare" you ask about is really a CmdLet which is just a type of function that has many lines.  That functionality is part of base PowerShell.  What you are asking for does not exist in PowerShell or in any language and would take a number of lines to create.  Understanding programming and programmed systems (computers) would help you to understand this and know why this might be.

    If this is something you need to do regularly then you can turn the code into a CmdLet and use that as one line.

    Here is how to create a CmdLet that does what you ask in one line:

    function Compare-VersionLists{
        [OutputType([string])]
        param(
            [version[]]$Versions,
            [version[]]$TargetList
        )
        
        foreach($q in $Versions){
            if($TargetList | %{$q -gt $_}|where{$_}){
                [string]$q
            }
        }
    }
    $dev = '2.2.3','2.3.4','2.5.6'
    $qa = '1.1.1','2.2.7'
    Compare-VersionLists $qa $dev


    \_(ツ)_/

    Saturday, February 29, 2020 12:45 PM