Given this function:
> function Get-ArrayOfArrays() {
(1,2),(3,4) | % { $_ }
}
I'd expect the return type to be an array of arrays. However, it appears that the inner arrays are being expanded into the pipe:
> Get-ArrayOfArrays | % { $_.GetType().Name }
Int32
Int32
Int32
Int32
In fact, running the pipe inline will produce these results:
> (1,2),(3,4) | % { $_ }
Object[]
Object[]
I've found that if I use the return keyword inside the foreach, I can achieve the desired result:
> function Get-ArrayOfArraysWithReturn() {
(1,2),(3,4) | % { return $_ }
}
> Get-ArrayOfArraysWithReturn | % { $_.GetType().Name }
Object[]
Object[]
This behavior seems to be "If returning from a function with uncaptured objects, and those objects happen to be arrays, then expand them". Is this one of those "do-what-is-useful-most-of-the-time" design decisions? Or am I missing something else?
(1,2),(3,4) | % {$_}
results in your function outputting (1,2) and (3,4) - the same as this function would:
function foo {
1,2
3,4
}
The kicker is that each of these arrays have their content's unrolled (flattened) again as part of the process of a function outputting objects e.g.:
PS> foo | %{$_.GetType().Name}
Int32
Int32
Int32
Int32
This is similar to what you see on the host when you execute this:
PS> 1,2
1
2
The array is unrolled such that each element of the array is displayed. The following should do what you want:
function Get-ArrayOfArrays() {
(1,2),(3,4)
}
When (1,2),(3,4) hits the function output it is unrolled once, outputting (1,2) and (3,4). Another technique you can use to work-around collection unrolling is to wrap a collection within another single element collection using the , operator to preserve the shape of the original collection e.g.:
PS> function foo { ,((1,2),(3,4)) }
PS> foo | gtn
Object[]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With