Search code examples
arrayspowershellmultidimensional-array

Questionable output while iterating over an array of arrays


I'm building an array of arrays in Powershell with the goal of iterating over that array and outputting strings from each member element. However in doing so, I'm getting fragments that aren't making sense.

The code starts off like this:

$details = @()

$row = @(6.00, "First", "Normal", 20, "")
$details += $row

$row = @(12.00, "First", "Normal", 12, "")
$details += $row

Then iterating over each $row using a foreach loop as follows:

foreach ($item in $details) {
    $price = $item[0]
    $edition = $item[1]
    $printing = $item[2]
    $stock = $item[3]
    $modifier = $item[4]
    $string = i

    $debug = "Added data for : $edition / $print  ..."
}

But outputting $debug. I get

Added data for: i / r ...
Added data for: i / r ...

It should be outputting:

First / Normal

Solution

  • PowerShell's polymorphic + operator, when applied to arrays, performs flat array concatenation.
    That is, if the RHS is an array too, its elements are "appended" to the LHS array, not the RHS array as a whole, as a single element.

    Therefore,

    $row = @(6.00, "First", "Normal", 20, "")
    $details += $row
    

    does not "append"[1] the array stored in $row as a single element to the $details array, but appends $row's elements, one by one.

    • A simple demonstration:

       $array = @('foo')
       $array += @('bar', 'baz')
       # -> @('foo', 'bar', 'baz')
      

    Use the unary form of , the array constructor ("comma") operator in order to add an array as a single element to a given array, i.e. as a nested array:

    $details = @()
    $row = @(6.00, "First", "Normal", 20, "")
    $details += , $row
    
    $details[0][0] # -> 6.00
    

    [1] Technically, because .NET arrays are fixed-size data structures, you can not append to them (change their size). What + does in PowerShell is to create a new array behind the scenes, comprising the LHS elements as well as the RHS ones.
    Also note that this implies that using += in a loop with many iterations is therefore best avoided so as to avoid performance problems; see this answer for details.