首页 > 解决方案 > PowerShell 枚举一个仅包含一个内部数组的数组

问题描述

考虑一下:这是一个数组,仅包含一项。而数组的项是另一个数组(我称之为列表对象)。我想获取数组中唯一的列表对象。

我使用 foreach 来获取列表,但它将列表对象视为数组并返回列表对象的第一项。

$OSName1 = @(
    @("win2008r2")
)
$OSName2 = @(
    @("win2008r2"),
    @("win2012")
)


foreach ($osname in $OSName1) {
    write-host $osname[0]
}

foreach ($osname in $OSName2) {
    write-host $osname[0]
}

我希望结果的输出是:win2008r2 win2008r2 win2012

但真正的结果是 w win2008r2 win2012 为什么 powershell auto 将内部数组扩展到它的父级?

标签: arrayslistpowershell

解决方案


您误解了数组构造和@()运算符在 PowerShell 中的一般工作方式。如果您查看 2 个数组变量的值,您会注意到只有第二个有嵌套数组:

PS C:\> ConvertTo-Json $OSName1
[
    “win2008r2”
]
PS C:\> ConvertTo-Json $OSName2
[
    [
        “win2008r2”
    ],
    [
        “win2012”
    ]
]

这是因为数组子表达式运算符@()计算嵌套表达式,然后将结果作为数组返回。但是,当您将一个数组子表达式嵌套到另一个数组子表达式中时,内部子表达式的结果会在外部子表达式的求值时自动展开。因此,您的第一个变量变为['win2008r2']而不是预期的[['win2008r2']].

您的第二个示例按您期望的方式工作,因为外部数组子表达式不仅包含嵌套数组子表达式,还包含嵌套子表达式数组

@(...), @(...)
      ^
       `- this comma is what actually creates the array of arrays

外部数组子表达式仅展开外部数组,因此结果最终仍然是一个数组数组。基本上,您不需要外部@()来获得所需的结果。删除它,您将得到完全相同的结果:

$OSName2 = @("win2008r2"), @("win2012")

要仅使用单个嵌套数组获得类似的结果,您需要使用一元数组构造运算符:

$OSName1 = ,@("win2008r2")

推荐阅读