Skip to content

Instantly share code, notes, and snippets.

@bigbadmoshe
Created June 14, 2023 09:46
Show Gist options
  • Save bigbadmoshe/6043c48f25c5ecc5fcc8935c77efb86e to your computer and use it in GitHub Desktop.
Save bigbadmoshe/6043c48f25c5ecc5fcc8935c77efb86e to your computer and use it in GitHub Desktop.
3 ways to sort a list unique

3 ways to sort a list unique

https://devdojo.com/hcritter/3-ways-to-sort-a-list-unique

Sort-Object -Unique Get-Unique HashSet-Class First we will create 3 different lists containing random strings in several sizes (small, medium, large)

#List elements
$ListOptionA ="Blue","Red","Green"
$ListOptionb ="Dog","Horse","Cat"

#Create a small set of strings based on list elemtents and a random number
$ListSmall = (0..100).ForEach({
 "$($ListOptionA[$(Get-Random -Minimum 0 -Maximum ($ListOptionA.count-1))])_$($ListOptionB[$(Get-Random -Minimum 0 -Maximum ($ListOptionB.count-1))])_$(Get-Random -Maximum 10 -Minimum 0)"
})

#Create a medium set of strings based on list elemtents and a random number
$ListMedium = (0..10000).ForEach({
 "$($ListOptionA[$(Get-Random -Minimum 0 -Maximum ($ListOptionA.count-1))])_$($ListOptionB[$(Get-Random -Minimum 0 -Maximum ($ListOptionB.count-1))])_$(Get-Random -Maximum 10 -Minimum 0)"
})

#Create a large set of strings based on list elemtents and a random number
$ListLarge = (0..1000000).ForEach({
 "$($ListOptionA[$(Get-Random -Minimum 0 -Maximum ($ListOptionA.count-1))])_$($ListOptionB[$(Get-Random -Minimum 0 -Maximum ($ListOptionB.count-1))])_$(Get-Random -Maximum 10 -Minimum 0)"
})

Now we can start to fetch results:

$Results = New-Object -TypeName System.Collections.Generic.List[PSCustomObject]

$ListOptions = "Small","Medium","Large"
$Method = "Sort-Object -Unique"
$Index = 0
($ListSmall,$ListMedium,$ListLarge).ForEach({
    $StopWatch = New-Object System.Diagnostics.Stopwatch
    $StopWatch.Start()
    $UniqueList = $($_ | Sort-Object -Unique)
    $StopWatch.Stop()
    $Results.Add([PSCustomObject]@{
        MethodName = $Method
        ListSize = "$($ListOptions[$Index]) $($_.Count)"
        Result = $UniqueList.count
        TimeElapsed = $StopWatch.Elapsed
        TimeElapsedMS = $StopWatch.ElapsedMilliseconds
    })
    $Index++
})
$Method = "get-unique"
$Index = 0
($ListSmall,$ListMedium,$ListLarge).ForEach({
    $StopWatch = New-Object System.Diagnostics.Stopwatch
    $StopWatch.Start()
    $UniqueList = $($_ | Sort-Object | get-Unique)
    $StopWatch.Stop()
    $Results.Add([PSCustomObject]@{
        MethodName = $Method
        ListSize = "$($ListOptions[$Index]) $($_.Count)"
        Result = $UniqueList.count
        TimeElapsed = $StopWatch.Elapsed
        TimeElapsedMS = $StopWatch.ElapsedMilliseconds
    })
    $Index++
})
$Method = "Hashset"
$Index = 0
($ListSmall,$ListMedium,$ListLarge).ForEach({
    $StopWatch = New-Object System.Diagnostics.Stopwatch
    $StopWatch.Start()
    $HashSet = New-Object System.Collections.Generic.HashSet[string]
    foreach($Listelement in $_){
        $HashSet.Add($Listelement) | Out-Null
    }
    $StopWatch.Stop()
    $Results.Add([PSCustomObject]@{
        MethodName = $Method
        ListSize = "$($ListOptions[$Index]) $($_.Count)"
        Result = $HashSet.count
        TimeElapsed = $StopWatch.Elapsed
        TimeElapsedMS = $StopWatch.ElapsedMilliseconds
    })
    $Index++
})

Which conclusion can we get from this table above? At first not one of them is the best solution for any situation. We should choose Sort-Object -unique for lists from 0 up to 1000 elements. If the list increases dramatically we should choose the Hashset approach. Also we should not use get-unique, because to make this work we have to sort the list first and this is more time consuming as to use the plain sort-object method like you can see this in the result-table.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment