Last active
April 27, 2023 16:03
-
-
Save PanosGreg/8fcfcff661f277cd1bab5eb8c63a6061 to your computer and use it in GitHub Desktop.
3 different options to Sort
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 3 different options to Sort: | |
# 1) via an IComparer class, | |
# using the Sort() method from List and ArrayList | |
# or just instantiate a SortedSet | |
# 2) via LINQ | |
# using the OrderBy() method | |
# 3) via Sort() method from [Array] | |
## Custom IComparer for use with: | |
# - System.Collections.Generic.List | |
# - System.Collections.Generic.SortedSet | |
# - System.Collections.ArrayList | |
class ObjectComparer : Collections.Generic.IComparer[Management.Automation.PSObject] { | |
[string]$PropertyName | |
[bool]$Descending = $false | |
#region --- Constructors | |
ObjectComparer([string]$Property) { | |
$this.PropertyName = $Property | |
} | |
ObjectComparer([string]$Property, [bool]$Descending) { | |
$this.PropertyName = $Property | |
$this.Descending = $Descending | |
} | |
#endregion | |
#region --- Compare method | |
[int] Compare ([Management.Automation.PSObject]$a, | |
[Management.Automation.PSObject]$b) { | |
$ValueA = $a.$($this.PropertyName) | |
$ValueB = $b.$($this.PropertyName) | |
if ($ValueA -eq $ValueB) {$result = 0} | |
elseif ($ValueA -lt $ValueB) {$result = -1} | |
else {$result = 1} | |
if($this.Descending) {$result *= -1} | |
return $result | |
} | |
#endregion | |
} | |
# Create a list | |
$list = [System.Collections.Generic.List[pscustomobject]]::new() | |
# create some ps objects | |
$a = [pscustomobject] @{Name = 'aa' ; Size = 10} | |
$b = [pscustomobject] @{Name = 'bb' ; Size = 20} | |
$c = [pscustomobject] @{Name = 'cc' ; Size = 30} | |
# add them to the list in an unsorted order | |
$c,$a,$b | ForEach-Object {$list.Add($_)} | |
# have a look at the unsorted list | |
$list | |
# Instantiate a comparer based on the 'Name' property | |
$NameComparer = [ObjectComparer]::new('Name') | |
# Now sort the list | |
$list.Sort($NameComparer) # <-- it sorts in-place | |
# Have a look at the sorted list | |
$list | |
## you could also do the same with a SortedSet as well | |
$set = [System.Collections.Generic.SortedSet[pscustomobject]]::new($NameComparer) | |
$c,$a,$b | ForEach-Object {[void]$set.Add($_)} | |
$set | |
### NOTE: of course you can change the Comparer class to use different kinds of object types | |
# for ex. [IO.FileSystemInfo], [IO.DirectoryInfo], [Diagnostics.Process], [ServiceProcess.ServiceController], etc. | |
###### Alternatively you can sort with LINQ | |
$objects = $c,$a,$b | |
[Linq.Enumerable]::OrderBy([pscustomobject[]]$objects, [Func[pscustomobject,string]] {($args[0]).Name}) | |
# LINQ is the only option that does NOT sort in-place, instead it outputs the results into a new object | |
### Or just use [array] (to sort based on the Name) | |
[array]::Sort($objects.Name,$objects) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment