查询PSCustomObject数组中值最大的行



我试图找到一个属性大于另一行属性的行。示例:

$Array
Name         Value
----         ----
test1         105
test2         101
test3         512   <--- Selects this row as it is the largest value

这是我尝试"1行"这个,但它不起作用。

$Array | % { If($_.value -gt $Array[0..($Array.Count)].value){write-host "$_.name is the largest row"}}

目前它什么也不输出。

所需输出:

"test1 is the largest row"

我很难想象如何在没有一些严肃的意大利面条代码的情况下有效地做到这一点。

您可以利用Sort-Object按属性"对它们进行排名;值";像这个

$array = @(
[PSCustomObject]@{Name='test1';Value=105}
[PSCustomObject]@{Name='test2';Value=101}
[PSCustomObject]@{Name='test3';Value=512}
)
$array | Sort-Object -Property value -Descending | Select-Object -First 1

输出

Name  Value
----  -----
test3   512

要合并您的写入主机,您只需通过foreach运行您选择的主机即可。

$array | Sort-Object -Property value -Descending |
Select-Object -First 1 | Foreach-Object {Write-host $_.name,"has the highest value"}
test3 has the highest value

或捕获到可变

$Largest = $array | Sort-Object -Property value -Descending | Select-Object -First 1
Write-host $Largest.name,"has the highest value"
test3 has the highest value

PowerShell有许多内置功能,可以使此类任务更轻松。

如果这真的是一个PSCustomObjects数组,你可以做一些类似的事情:

$Array = 
@(
[PSCustomObject]@{ Name = 'test1'; Value = 105 }
[PSCustomObject]@{ Name = 'test2'; Value = 101 }
[PSCustomObject]@{ Name = 'test3'; Value = 512 }
)
$Largest = ($Array | Sort-Object Value)[-1].Name
Write-host $Largest,"has the highest value"

这将根据Value属性对数组进行排序。然后使用[-1]语法引用最后一个元素,然后返回该对象的name属性。

或者,如果你是一个纯粹主义者,你可以分配变量,比如:

$Largest = $Array |  Sort-Object Value | Select-Object -Last 1 -ExpandProperty Name

如果您想要整个对象,只需删除.Name&CCD_ 4。


更新:

如前所述,PowerShell有一些很棒的工具来帮助完成常见任务,如排序&选择数据。然而,这并不意味着永远不需要循环结构。因此,我想就OP自己的答案提出几点看法。

首先,如果您确实需要通过索引引用数组元素,请使用传统的For循环,它可能看起来像:

For( $i = 0; $i -lt $Array.Count; ++$i )
{
If( $array[$i].Value -gt $LargestValue )
{
$LargestName  = $array[$i].Name
$LargestValue = $array[$i].Value        
}
}

$i通常用作迭代变量,在脚本块中用作数组索引。

其次,在这种情况下,即使是传统的循环也是不必要的。您可以坚持使用ForEach循环,并在遇到最大值时跟踪它。这可能看起来像:

ForEach( $Row in $array )
{
If( $Row.Value -gt $LargestValue )
{
$LargestName  = $Row.Name
$LargestValue = $Row.Value        
}
}

严格地说,你不需要事先分配变量,尽管在这两个变量之前加上可能是一个很好的做法

$LargestName  = ""
$LargestValue = 0

在这些示例中,您必须使用稍微修改过的Write-Host命令

Write-host $LargestName,"has the highest value"

注:借用了Doug Maurer的Fine Answer中的一些测试代码。考虑到我们的答案相似,这只是为了让我的例子对问题更清楚,更容易测试。

想清楚了,希望这并不可怕:

$Count = 1
$CurrentLargest = 0
Foreach($Row in $Array) {

# Compare This iteration vs the next to find the largest
If($Row.value -gt $Array.Value[$Count]){$CurrentLargest = $Row}
Else {$CurrentLargest = $Array[$Count]}

# Replace the existing largest value with the new one if it is larger than it.
If($CurrentLargest.Value -gt $Largest.Value){ $Largest = $CurrentLargest }

$Count += 1
}
Write-host $Largest.name,"has the highest value"

编辑:太糟糕了,看看其他答案,找到更好的方法。

最新更新