Observe this example:
PS C:\> $list=("A","B")
PS C:\> $list.GetType().Name
Object[]
PS C:\> ($list | ? {$_ -ne "C"}).GetType().Name
Object[]
PS C:\> ($list | ? {$_ -ne "B"}).GetType().Name
String
Why on earth is Powershell converting my array to a String when there's only one element left? It breaks further processing of the variable in my script where I assume the output is an Array. How can I prevent it?
To explain why Powershell seemingly converts an array to a string is caused by the result of Where-Object / %
's filtering and data it returns.
When the first version filters elements not equal to "C", the result is a collection. There were more than one matching member: "A" and "B". Thus, a collection is needed to contain both values.
The second version returns just a single object, "A", and thus it's a string instead of a collection. Since there is just a single object, there is no need to return an array with one element - just the object itself.
Theo's answer works by making Where-Object
's output to be an array. The array sub-expression operator @()
can be used to create arrays. Like so,
# Convert where-object's output into an array,
# even if there is only a single object.
@($list | ? {$_ -ne "B"})
To complement my comment and vonPryz's answer
PowerShell 'unravels' one-element arrays when returning from a function or scriptblock into a single scalar, in this case a string.
To prevent that from interfering with the rest of the code which expects an array, no matter if it is empty or has only one element, you can force the output to become an array by wrapping it inside @()
.
In your case,
($list | ? {$_ -ne "B"})
would return the single element A
, turned into a scalar String
, while
@($list | ? {$_ -ne "B"}).GetType().Name
returns an array (Object[]
) with just one element in it.
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