-
PowerShell by default enumerates (unrolls) collections[1] when outputting them to the pipeline: that is, instead of outputting the collection itself, its elements are output, one by one.
-
电源外壳将管道中的所有输出对象收集到平面数组中(类型[object[]]
,即一个数组,其元素可以是任何类型(System.Object)), if 两个或更多输出对象(asingle对象被收集本身).
因此,即使输出multiple数组创建一个single,默认情况下平面输出数组,这是级联这些数组。
一个更简单的例子:
# Output 2 2-element arrays.
PS> 1..2 | % { @(1, 2) } | Measure-Object | % Count
4 # i.e., @(1, 2, 1, 2).Count
为了生产nested数组,你必须抑制枚举,可以通过两种方式实现:
- 最简单的选择:将输出数组包装在辅助瞬态单元阵列这样当 PowerShell 枚举 aux.数组其唯一的元素 - 原始数组 - 是输出作为一个整体, as a 单个对象。这可以通过以下方式实现一元形式
,
the 数组构造函数(“逗号”)运算符:
# Use unary , to wrap the RHS in a transient single-element array,
# which ensures that @(1, 2) is output *as a whole*.
PS> 1..2 | % { , @(1, 2) } | Measure-Object | % Count
2 # i.e., @(@(1, 2), @(1, 2)).Count
- 替代方案,使用
Write-Output -NoEnumerate
(PSv4+;这更慢,但概念上更明确):
PS> 1..2 | % { Write-Output -NoEnumerate @(1, 2) } | Measure-Object | % Count
2 # i.e., @(@(1, 2), @(1, 2)).Count
Note:
- While use of
@(...)
is not strictly necessary to create array literals (as used above) - for literals, separating elements with ,
is sufficient[2] - you still need @(...)
to ensure that output from enclosed expressions or commands is treated as an array, in case only a single object happens to be output.
[1] Specifically, types that implement the System.Collections.IEnumerable interface or its generic counterpart are enumerated, but there are a few exceptions, notably strings and dictionaries. See the bottom section of this answer for details.
[2] E.g., 1, 2
creates a two-element array. In the case of nesting such an array via unary ,
, you do need an enclosure, however, to clarify precedence, for which the general-purpose (...)
(grouping operator) would suffice: , (1, 2)
- though you may prefer , @(1, 2)
for conceptual clarity.