PowerShell 枚举仅包含一个内部数组的数组

4
考虑以下情况: 这是一个数组,只包含一个项目。该项目是另一个数组(我称其为列表对象)。 我想要获取数组中唯一的列表对象。
我使用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自动将内部数组扩展到其父级?


我猜它认为第一个是字符串,所以$osname[0]是第一个字符(w)。 - Nick.McDermaid
但我已经明确地将其指定为带有@()的项。 - Aaron Hu
为什么PowerShell会自动将内部数组扩展到其父级?因为这是PowerShell的本质和过度热衷于管道 :) - Mathias R. Jessen
如何避免它?我尝试添加 @(),但似乎 PowerShell 没有接受它。 - Aaron Hu
2个回答

6
您误解了PowerShell中的数组构造和特定的@()运算符。如果您查看两个数组变量的值,您会注意到只有第二个变量具有嵌套数组:
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")

-1

除了Ansgar的解释之外,你只需要一个嵌套数组就可以实现你所需的功能。

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


foreach ($osname in $OSName1) 
{
    $OSName
    foreach($OS2 in $OSName2 )
    {
    $OS2
    }
}

希望它有所帮助。


你的代码没有创建嵌套数组(而且数组的声明方式与问题中的相同)。你是指嵌套循环吗?为什么需要嵌套循环?另外,你的答案与Ansgar的解释实际问题之间的关系也不清楚。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接