3
$arrays = @();
$array  = @();
$string = 'one|two|three';
$array  = ($string -split '\|');
$arrays += $array;
$arrays[0][0]

I expected $arrays to be a two dimensional array the first element of which would be a reference to $array. Thus, $arrays[0][0] would contain the string 'one'.

Instead PoSh seems to be flattening $arrays into a single list containing the elements 'one', 'two', and 'three'. This is true even if I put the @() array constructor around $array in my append operation.

Adding an additional element to my append gets me close, but then I'll have empty elements in $arrays:

$arrays = @();
$array  = @();
$string = 'one|two|three';
$array  = ($string -split '\|');
$arrays += $array, '';
$arrays[0][0]
Itchydon
  • 2,572
  • 6
  • 19
  • 33

2 Answers2

3

Think of PowerShell's + operator with an array as the LHS as concatenating arrays, i.e., appending the individual elements of the RHS to the LHS array[1] :

# Note: , has higher precedence than +, so this is the same as: ((1, 2) + (3, 4)).Count
> (1, 2 + 3, 4).Count # Same as: (1, 2, 3, 4).Count
4

even if I put the @() array constructor around $array

It is , that is the array-construction operator.

@() is the array sub-expression operator - its purpose is to ensure that the output from the enclosed command becomes an array unless it already is one.
In other words: Something like @(1, 2) is a no-op, because 1, 2 already is an array.

Therefore, as you've discovered, using , to construct a nested array is the solution:

> (1, 2 + , (3, 4)).Count
3
  • , (3, 4) wraps array 3, 4 in a single-element array.

  • + then adds each element of that array - the one and only element that is the wrapped 3, 4 array - to the LHS.


[1] Let's not forget that a .NET array is an immutable data structure, so what is really happening is that, behind the scenes, PowerShell constructs a new array.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    These are extremely useful details. Thank you so much for explaining this. Understanding that `,` is actually the array-construction operator makes this seem less like PoSh is doing squirrely things behind the scenes. – Charles Gamble Jul 13 '17 at 14:15
2

After some additional research I found this post. This is, apparently, done by design. Adding a comma prior to $array in my append operation fixes the problem:

$arrays = @();
$array  = @();
$string = 'one|two|three';
$array  = ($string -split '\|');
$arrays += ,$array;
$arrays[0][0]