Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

list - PowerShell enumerate an array that contains only one inner array

Conside this: This is one array and contains only one item. And the item of the array is another array(I call it list object). I want to get the only list object inside an array.

I use foreach to get the list, but it treates the list object as an array and return the first item of the list object.

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


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

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

I expect the output of result is: win2008r2 win2008r2 win2012

But the real result is w win2008r2 win2012 Why powershell auto expands the inside array to it parent?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're misunderstanding how array construction in general and the @() operator in particular work in PowerShell. If you take a look at the value of your 2 array variables you'll notice that only the second one has nested arrays:

PS C:> ConvertTo-Json $OSName1
[
    "win2008r2"
]
PS C:> ConvertTo-Json $OSName2
[
    [
        "win2008r2"
    ],
    [
        "win2012"
    ]
]

That is because the array subexpression operator @() evaluates the nested expression and then returns the result as an array. But when you're nesting an array subexpression into another array subexpression the result of the inner subexpression is automatically unrolled upon the evalution of the outer subexpression. Because of that your first variable becomes ['win2008r2'] instead of the intended [['win2008r2']].

Your second example works the way you expect because the outer array subexpression contains not just a nested array subexpression, but an array of nested subexpressions:

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

The outer array subexpression unrolls only the outer array, so that the result is still an array of arrays in the end. Basically, you don't need the outer @() for the desired result. Remove it and you will get the exact same result:

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

To get a similar result with just a single nested array you need to use the unary array construction operator:

$OSName1 = ,@("win2008r2")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...