Foreach管道返回类型

时间:2017-09-20 14:06:59

标签: powershell

我不确定我的标题是我问题的最佳描述。考虑这个最小的工作示例:

$arr = @()

$object = New-Object -TypeName PSObject
$object | Add-Member –MemberType NoteProperty –Name Name –Value "Fred"
$object | Add-Member –MemberType NoteProperty –Name Rank –Value "2"

$arr += $object

$object = New-Object -TypeName PSObject
$object | Add-Member –MemberType NoteProperty –Name Name –Value "Joe"
$object | Add-Member –MemberType NoteProperty –Name Rank –Value "1"

$arr += $object

$object = New-Object -TypeName PSObject
$object | Add-Member –MemberType NoteProperty –Name Name –Value "Ann"
$object | Add-Member –MemberType NoteProperty –Name Rank –Value "4"

$arr += $object

$arr

($arr | foreach { if($_.Rank -gt 1) { $_ } }).GetType() | FT
($arr | foreach { if($_.Rank -le 1) { $_ } }).GetType() | FT

这是

的输出
Name Rank
---- ----
Fred 2   
Joe  1   
Ann  4   



IsPublic IsSerial Name     BaseType    
-------- -------- ----     --------    
True     True     Object[] System.Array



IsPublic IsSerial Name           BaseType     
-------- -------- ----           --------     
True     False    PSCustomObject System.Object

尝试对结果的foreach命令数组进行额外处理时,我的问题就存在了。可以想象,$ arr的输入数据每次都会有所不同,匹配结果的数量也会不同。根据匹配结果的数量,数据类型不同。 我想要的是返回一个对象数组,但是在只有一个匹配的情况下,它只返回对象。如果我尝试使用计算索引从数组中获取信息,我会得到截然不同的结果,具体取决于它是一个对象还是一个对象数组。

希望有人为我提供解决方案!谢谢!

2 个答案:

答案 0 :(得分:3)

@()

围绕表达式
@($arr | foreach { if($_.Rank -le 1) { $_ } }).GetType() | FT

这将始终产生一个数组。

答案 1 :(得分:1)

您可以使用WriteObject并指定enumerateCollection参数,在任何函数发出1个或多个对象的内部处理此问题:

function Get-ArrayOfThings
{
    [CmdletBinding()]
    param(
        [ValidateRange(1,100)]
        [int]$Count = 3
    )

    $PSCmdlet.WriteObject(@(1..$Count), $false)
}
(Get-ArrayOfThings -Count 5).GetType() # shows System.Object[]
(Get-ArrayOfThings -Count 1).GetType() # still System.Object[]

或者您可以使用数组子表达式在调用者端强制执行它:

$ArrayOfOneOrMoreThings = @($OneOrMoreThings)