有一个对象数组,每个对象都有一个对象集合,每个对象都有一个字符串属性。当我进行嵌套迭代时:
FROM node:8.9-alpine
似乎我最终没有使用字符串数组数组,而是使用一维字符串数组。这是设计的吗? 首先是所需的行为,但完全出乎意料。
答案 0 :(得分:1)
是的,这个输出对我来说很有意义,至少在直观的层面上是这样。我无法用准确的技术细节来解释,而是在表达式中写入管道的唯一对象
$TheArray | %{$_.TheCollection | %{$_.TheProperty} }
是最内层的
$_.TheProperty
由于此求值为String,因此在管道中累积了许多字符串并以数组形式返回。
以下是一些示例代码,可以模拟您所描述的内容:
class HasProperty {
[String] $TheProperty;
HasProperty ([String] $prop){
$this.TheProperty = $prop
}
}
class SomeObject {
[HasProperty[]] $TheCollection
SomeObject ([HasProperty[]] $array) {
$this.TheCollection = $array
}
}
[SomeObject[]]$TheArray = @()
$TheArray = foreach ($i in (0..9)) {
[HasProperty[]]$tempArray = foreach ($n in (0..3)) { [HasProperty]::new("Property$i-$n") }
[SomeObject]::new($tempArray)
}
$TheArray | %{$_.TheCollection | %{$_.TheProperty} }
PowerShell的面向对象管道可以轻松地从某些对象集合中提取值。例如,我用它来获取用户集合的成员资格,以确定其成员资格如何重叠。
答案 1 :(得分:0)
PowerShell 默认枚举(取消分析)集合,将它们输出到管道时:集合的元素逐个输出
PowerShell 从平面阵列中的管道收集所有输出对象。
因此,即使输出多个数组,默认情况下也会创建一个单个,平面输出数组,这是这些数组的连接。
一个更简单的例子:
# Output 2 2-element arrays.
> 1..2 | % { @(1, 2) } | Measure-Object | % Count
4 # i.e., @(1, 2, 1, 2).Count
为了生成嵌套数组,您必须抑制枚举,这可以通过两种方式实现:
# Use unary , to wrap the RHS in a single-element array.
> 1..2 | % { , @(1, 2) } | Measure-Object | % Count
2 # i.e., @(@(1, 2), @(1, 2)).Count
Write-Output -NoEnumerate
(PSv4 +):> 1..2 | % { Write-Output -NoEnumerate @(1, 2) } | Measure-Object | % Count
2 # i.e., @(@(1, 2), @(1, 2)).Count
注意:虽然不需要使用@(...)
来创建数组文字(如上所述) - 对于文字,使用,
分隔元素就足够了 - 您仍然需要@(...)
确保封闭表达式或命令的输出被视为数组,以防只输出单个对象。