嵌套For-Each变平?

时间:2018-01-19 21:03:22

标签: powershell

有一个对象数组,每个对象都有一个对象集合,每个对象都有一个字符串属性。当我进行嵌套迭代时:

FROM node:8.9-alpine

似乎我最终没有使用字符串数组数组,而是使用一维字符串数组。这是设计的吗? 首先是所需的行为,但完全出乎意料。

2 个答案:

答案 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

为了生成嵌套数组,您必须抑制枚举,这可以通过两种方式实现:

  • 最简单的选项:将输出数组包装在 aux中。外部数组 ,以便枚举外部数组会将嵌入的数组生成为单个输出对象:
# 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

注意:虽然不需要使用@(...)来创建数组文字(如上所述) - 对于文字,使用,分隔元素就足够了 - 您仍然需要@(...)确保封闭表达式或命令的输出被视为数组,以防只输出单个对象。

相关问题