Array Literals In PowerShell

The first thing to understand is that there are no array literals in PowerShell J Arrays are built using operators or casts. The way to build an array in PowerShell is to use the comma operator as shown in the following examples:

 

$a = , 1          # array of one element

$a = 1,2          # array of two elements

$a = 1,2,3        # array of three elements.

$a = (1,2),(3,4)  # array of two elements, each of which is a two element array

$a += ,(5,6)      # add another element which is an array of two element.

 

Now let’s display the array we’ve built. Simply displaying the variable isn’t very helpful since PowerShell will unravel everything in the display process obscuring the inner structure. Instead we’ll use individual indexing operations to look at each piece:

 

PS (61) > $a[0]

1

2

PS (62) > $a[1]

3

4

PS (63) > $a[2]

5

6

 

The comma operator is the array construction operator in PowerShell (similar to the cons function in LISP.)

 

By now, if you’re familiar with PowerShell, you’re asking – so what’s with the @() notation? If it isn’t an array literal, then what is it? First let’s talk about arrays and casts. The other way to build an array is through a covariant conversions or casts. In PowerShell, this includes the ability to cast a scalar object into an array. In the following example, we’re casting an integer into an array:

 

PS (64) > $a = [array] 1

PS (65) > $a[0]

1

 

Now, since it’s already an array, casting it again doesn’t result in a second level of nesting:

 

PS (66) > $a = [array] [array] 1

PS (67) > $a[0]

1

 

However using 2 commas *does* nest the array since it is the array construction operation:

 

PS (68) > $a = ,,1

PS (69) > $a[0][0]

1

 

Now on to @(). In essence, the @( … ) operation is syntactic sugar for

 

[array] $( … )

 

 So – if the statements in @() return a scalar, it will be wrapped in an array but if the result is already an array, then it won’t be nested.

 

And finally, why did we do it this way? The goal was to make array operations consistent with the command argument syntax. A comma on the command line indicates a collection of objects bound to one parameter.

 

PS (77) > function f([array] $x, [array] $y, [array] $z) {$x.count; $y.count, $z.count}

PS (78) > foo a,b,c z l,m

3

1

2

 

And why have @() at all? Because pipelines in a value context gather their results from a stream. From the stream you can’t tell whether the pipeline returned a singleton or a collection. Using the @() means that you don’t really have to care. If you might receive a collection, then just use

 

$result = @( … pipeline … )

 

and it doesn’t matter what you receive, it will always be an array.

 

-bruce

 

Bruce Payette [MSFT]

Windows PowerShell Tech Lead

 

Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell

Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Windows PowerShell in Action (book): http://manning.com/powershell