jdel
jdel

Reputation: 51

Why does Powershell combines array of arrays?

I use arrays of arrays in a Powershell script, however, sometimes, my array of arrays, actually contains only one array. For some reason, Powershell keeps replacing that array containing one array, by just one array. I don't get it, no other scripting / coding language I ever used has done that before.

Example, this is what I do not want:

PS C:\Users\> $a = @(@(123,456,789))
PS C:\Users\> $a[0]
123

This is what I want:

PS C:\Users\> $a = @(@(123,456,789), @())
PS C:\Users\> $a[0]
123
456
789

Why do I have to force an extra empty array for Powershell to consider my array of arrays as such when it only contains one array ? This is driving me nuts !

Upvotes: 2

Views: 242

Answers (2)

user4003407
user4003407

Reputation: 22132

@() operator interpret its content as statements not as expression. Let us put explicit ;.

@(@(123,456,789;);)

What do you have here:

  1. 123,456,789 — binary comma operator create an array with three elements.
    Result: array [123,456,789].
  2. 123,456,789; — as expression in this statement return collection, PowerShell enumerate this collection and write collection's elements (not collection itself) to the pipeline.
    Result: three elements 123, 456 and 789 written to the pipeline.
  3. @(123,456,789;) — array subexpression operator collect all the items written to pipeline as result of invocation of nested statements and create array from them.
    Result: array [123,456,789].
  4. @(123,456,789;); — as expression in this statement return collection, PowerShell enumerate this collection and write collection's elements (not collection itself) to the pipeline.
    Result: three elements 123, 456 and 789 written to the pipeline.
  5. @(@(123,456,789;);) — array subexpression operator collect all the items written to pipeline as result of invocation of nested statements and create array from them.
    Result: array [123,456,789].

So, when you write @(collection), PowerShell return copy of collection, not collection wrapped into single element array. If you want to create array with single element, then you should use unary comma operator: ,expression. This will create single element array regardless of expression return collection or not.

Also, when you write @(a,b,c,etc), it is binary comma, who create array. Array subexpression operator just copy that array. But why do you need a copy? Is any reason, why you can not use original array? All you need for not making extra copy is just to omit @ character: (a,b,c,etc).

Upvotes: 0

Sean
Sean

Reputation: 62542

You need to put a comma as the first item:

 $a = @(, @(123,456,789) )

The reason for this is that the comma is essentially the array construction parameters. This MSDN article has more information.

Upvotes: 4

Related Questions