Andrzej Gis
Andrzej Gis

Reputation: 14306

Sorting objects by multiple properties

I'm trying to use PowerShell for sorting objects representing application verions

$versionsObjects = @{
    Major = 3
    Minor = 2
    Bugfix = 1
},
@{
    Major = 3
    Minor = 5
    Bugfix = 1
},
@{
    Major = 1
    Minor = 2
    Bugfix = 1
},
@{
    Major = 4
    Minor = 2
    Bugfix = 1
}

$sortedVersions = ($versionsObjects | Sort-Object -Property @{Expression="Major"; Descending=$true}, @{Expression="Minor" ;Descending=$true}, @{Expression="Bugfix"; Descending=$true})
$sortedVersions | %{echo ( "{0}.{1}.{2}" -f $_.Major, $_.Minor, $_.Bugfix)}

The output is in the same order as input:

3.2.1
3.5.1
1.2.1
4.2.1

But it should be

4.2.1
3.5.1
3.2.1
1.2.1

What am I doing wrong?

Upvotes: 10

Views: 15685

Answers (3)

Chris Martin
Chris Martin

Reputation: 393

I wasn't able to make it work with a hashtable , but I was successful when I sorted with a custom PSObject instead. Maybe it'll be helpful?

$versionsObjects = @()

$versionsObjects += New-Object -TypeName PSObject -Property @{Major = 3; Minor = 2 ; Bugfix = 1}
$versionsObjects += New-Object -TypeName PSObject -Property @{Major = 3; Minor = 5 ; Bugfix = 1}
$versionsObjects += New-Object -TypeName PSObject -Property @{Major = 1; Minor = 2 ; Bugfix = 1}
$versionsObjects += New-Object -TypeName PSObject -Property @{Major = 4; Minor = 2 ; Bugfix = 1}


$versionsObjects |

Sort-Object -Property Major,Minor,Bugfix -Descending |

ForEach-Object -Process {

echo ( "{0}.{1}.{2}" -f $_.Major, $_.Minor, $_.Bugfix)

                    }

Upvotes: 3

Mike Shepard
Mike Shepard

Reputation: 18166

Your expressions aren't quite right. Try this for the Sort-Object part:

Sort-Object -Property @{Expression={$_.Major}; Descending=$true}, @{Expression={$_.Minor} ;Descending=$true}, @{Expression={$_.Bugfix}; Descending=$true})

Upvotes: 13

CB.
CB.

Reputation: 60918

if you are at least in powershell v3.0 you can do it like this:

$versionsObjects = [ordered]@{
    Major = 3
    Minor = 2
    Bugfix = 1
},
[ordered]@{
    Major = 3
    Minor = 5
    Bugfix = 1
},
[ordered]@{
    Major = 1
    Minor = 2
    Bugfix = 1
},
[ordered]@{
    Major = 4
    Minor = 2
    Bugfix = 1
}

$versionsObjects | % { $_.values  -join '.' } | sort -Descending {[version]$_ }

or for all version:

$versionsObjects = @{
    Major = 3
    Minor = 2
    Bugfix = 1
},
@{
    Major = 3
    Minor = 5
    Bugfix = 1
},
@{
    Major = 1
    Minor = 2
    Bugfix = 1
},
@{
    Major = 4
    Minor = 2
    Bugfix = 1
}

$versionsObjects | % { $_.Major,$_.Minor,$_.bugfix  -join '.' } | sort -Descending {[version]$_ }

Upvotes: 3

Related Questions