1
$CustomObjects = Get-Random -Count 7 -InputObject @(0..300) | ForEach-Object {$i = 0} {
    [PSCustomObject]@{
        id = ($i++)
        value = $_
    }
}

$min, $max = & {$Args[0].Minimum, $Args[0].Maximum} ($CustomObjects | ForEach-Object value | Measure-Object -Minimum -Maximum)

$CustomObjects | Format-Table id, value -RepeatHeader
$CustomObjects | Where-Object {$_.value -eq $min} | Format-Table id, value 
$CustomObjects | Where-Object {$_.value -eq $max} | Format-Table id, value

Are there more interesting options for finding the minimum / maximum?

0

2 Answers 2

2

We could come up with a long list of valid PowerShell statements that all look slightly different and would yield the same result, but there's basically 2 ways:

  • Sorting
  • Keeping count

Obtaining min/max through sorting is exactly what it sounds like:

$min,$max = @($CustomObjects |Sort Value)[0,-1].Value
# or 
$min,$max = @($CustomObjects.Value |Sort)[0,-1]

Very succinct, easy to express - but might turn out to be slow on large collections

Obtaining min/max through keeping count is exactly what Measure-Object does:

$min,$max = [int]::MaxValue,[int]::MinValue
$CustomObjects |ForEach-Object {
  $min = [Math]::Min($_.Value, $min)
  $max = [Math]::Max($_.Value, $max)
}

Not as fancy, but faster for large collections

Sign up to request clarification or add additional context in comments.

Comments

1

Mathias R. Jessen's helpful answer shows elegant - but potentially wasteful in terms of memory - solutions (Sort-Object of necessity needs to collect all input objects in memory so as to be able to determine the sort order).

Your own, Measure-Object-based approach takes advantage of the memory-throttling property of the pipeline.

Due to use of PowerShell's pipeline, both approaches are likely to be slow, however - see this answer for a discussion.

A simple optimization of your approach is to make the ForEach-Object value pipeline segment unnecessary by passing -Property value to Measure-Object:

$CustomObjects | Measure-Object -Property value -Minimum -Maximum

The Microsoft.PowerShell.Commands.GenericMeasureInfo returned by this command has .Minimum and .Maximum properties, so there's no strict reason to create separate $min and $max variables, but if you wanted to:

$measureResult = $CustomObjects | Measure-Object -Property value -Minimum -Maximum
$min, $max = $measureResult.Minimum, $measureResult.Maximum

If you'd rather not create an auxiliary variable, you can use the following, which uses the .ForEach() array method:

$min, $max = ($CustomObjects | Measure-Object -Property value -Minimum -Maximum).
                ForEach({ $_.Minimum, $_.Maximum })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.