I have a Powershell function that returns an array of hashtables. If the function returns a single entry in the array, then I get some odd behaviour, is this expected?
For context:
- I’m a C# developer, so I’m expecting the return type to be consistent, regardless of the quantity of results 🙂
- Powershell Version: 5.1 on Windows 11
function GetArrayOfHashtable
{
param([string] $name, [int]$count)
$result = @()
for ($i = 0; $i -lt $count; $i++) {
$h = @{
name = $name
id=$i+1
}
$result += $h
}
return $result
}
$one = GetArrayOfHashtable "one" 1
$two = GetArrayOfHashtable "two" 2
$three = GetArrayOfHashtable "three" 3
Write-Host $one.gettype() # 'System.Collections.Hashtable' <--???
Write-Host $two.gettype() # 'System.Object[]'
Write-Host $three.gettype() # 'System.Object[]'
Write-Host $three[0].name $three[0].id # 'three 1'
Write-Host $two[0].name $two[0].id # 'two 1'
Write-Host $one[0].name $one[0].id # ''
Update (for completeness)
I can work around the issue by encapsulating the array of hashtables in another hashtable:
function GetArrayOfHashtable
{
param([string] $name, [int]$count)
$result = @()
for ($i = 0; $i -lt $count; $i++) {
$h = @{
name = $name
id=$i+1
}
$result += $h
}
return @{data =$result} # NOTE: solution is to hold the result in a hashtable
}
$one = GetArrayOfHashtable "one" 1
$two = GetArrayOfHashtable "two" 2
$three = GetArrayOfHashtable "three" 3
Write-Host $one.data.gettype() # 'System.Object[]'
Write-Host $two.data.gettype() # 'System.Object[]'
Write-Host $three.data.gettype() # 'System.Object[]'
Write-Host $three.data[0].name $three.data[0].id # 'three 1'
Write-Host $two.data[0].name $two.data[0].id # 'two 1'
Write-Host $one.data[0].name $one.data[0].id # 'one 1'
4
As per the comments, this looks to be expected behaviour as described here
One solution is to use the unary operator:
function GetArrayOfHashtable
{
param([string] $name, [int]$count)
$result = @()
for ($i = 0; $i -lt $count; $i++) {
$h = @{
name = $name
id=$i+1
}
$result += $h
}
return ,$result # <--- See comma here
}
or
change the call to use @( ... )
:
$one = @(GetArrayOfHashtable "one" 1)
3