PowerShell应该从管道返回对象[]?
鉴于此功能:PowerShell应该从管道返回对象[]?,powershell,Powershell,鉴于此功能: > function Get-ArrayOfArrays() { (1,2),(3,4) | % { $_ } } 我希望返回类型是数组的数组。但是,内部阵列似乎正在扩展到管道中: > Get-ArrayOfArrays | % { $_.GetType().Name } Int32 Int32 Int32 Int32 事实上,在线运行管道将产生以下结果: > (1,2),(3,4) | % { $_ } Object[] Object[] 我发现,
> function Get-ArrayOfArrays() {
(1,2),(3,4) | % { $_ }
}
我希望返回类型是数组的数组。但是,内部阵列似乎正在扩展到管道中:
> Get-ArrayOfArrays | % { $_.GetType().Name }
Int32
Int32
Int32
Int32
事实上,在线运行管道将产生以下结果:
> (1,2),(3,4) | % { $_ }
Object[]
Object[]
我发现,如果我在foreach中使用return关键字,我可以达到预期的结果:
> function Get-ArrayOfArraysWithReturn() {
(1,2),(3,4) | % { return $_ }
}
> Get-ArrayOfArraysWithReturn | % { $_.GetType().Name }
Object[]
Object[]
这种行为似乎是“如果从带有未捕获对象的函数返回,而这些对象恰好是数组,则展开它们”。这是一个“做大多数时候有用的事情”的设计决策吗?还是我错过了什么
(1,2),(3,4) | % {$_}
函数输出(1,2)和(3,4)的结果-与此函数相同:
function foo {
1,2
3,4
}
更重要的是,在函数输出对象(例如:
PS> foo | %{$_.GetType().Name}
Int32
Int32
Int32
Int32
这与执行此操作时在主机上看到的情况类似:
PS> 1,2
1
2
展开数组,以便显示数组的每个元素。以下操作应满足您的要求:
function Get-ArrayOfArrays() {
(1,2),(3,4)
}
当(1,2)、(3,4)点击函数输出时,它展开一次,输出(1,2)和(3,4)。解决集合展开的另一种方法是使用,
操作符将集合包装到另一个单个元素集合中,以保留原始集合的形状,例如:
PS> function foo { ,((1,2),(3,4)) }
PS> foo | gtn
Object[]
我想问一个类似的问题,即“如何防止PowerShell展开/加入/连接数组?” 我发现交互式解释器在控制台中打印结果之前会执行一个额外的展开步骤: 比如说
> (1, 2), (3, 4)
1
2
3
4
这意味着它已经展开过一次:
[ 1, 2 ] ++ [ 3, 4 ] == [ 1, 2, 3, 4 ]
因此,解释器打印的内容不一定是代码的实输出
例如,下面的代码
1, 2, 3 | ForEach-Object { $_, ($_ * 2) }
获取前三个整数,并为每个整数提供一个包含两个数字的列表。结果是:
[ 1, 2, 2, 4, 3, 6 ]
但是,我需要以下输出:
[ [ 1, 2 ], [ 2, 4 ], [ 3, 6 ] ]
我使用了逗号,
运算符,正如Keith Hill所建议的:
$list = 1, 2, 3 | ForEach-Object { , ($_, ($_ * 2)) }
因为我们为每个输入返回一个数组of,数组of,int:
1 -> [ [ 1, 2 ] ]
2 -> [ [ 2, 4 ] ]
3 -> [ [ 3, 6 ] ]
我们希望它只展开一次,以便$list
等于:
[ [ 1, 2 ] ] + [ [ 2, 4 ] ] + [ [ 3, 6 ] ] == [ [ 1, 2 ], [ 2, 4 ], [ 3, 6 ] ]
我们可以测试它是否正确
> $list[0] # get first element of list, should be [ 1, 2 ]
1
2
> $list[2][1] # from the third elem, [ 3, 6 ], get 2nd elem, should be 6
6
但是,当解释器打印列表时,它会再次展开列表:
[ 1, 2 ] ++ [ 2, 4 ] ++ [ 3, 6 ] == [ 1, 2, 2, 4, 3, 6 ]
所以我们得到了
> $list
# prints [ 1, 2, 2, 4, 3, 6 ]
阵列展平有时有点棘手,但非常有用。是的,大多数时候你不会考虑它(对Powershell团队来说很好),但在处理阵列并保持其形状时,你必须跳过一两个环。啊,有两个函数边界被击中,所以它被展开两次。有道理-谢谢你的解释。