I have an issue in PowerShell where a 1-element array returned from a function is not being returned as an array. I have found a number of places where similar questions have been asked(PowerShell: How can I to force to get a result as an Array instead of Object & How can I force Powershell to return an array when a call only returns one object?) but the solutions there don't work for me. Here's my code:
function x()
{
$levelMappings = @()
$levelMappings += @{"a"="b";"c"="d"}
return @($levelMappings)
}
(x).gettype().name
It returns
Hashtable
I don't want that, I want the thing that gets returned to always be an array even if it only has one element in it. I know i can get round this by explicitly converting the function's returned value to an array:
function x()
{
$levelMappings = @()
$levelMappings += @{"a"="b";"c"="d"}
return @($levelMappings)
}
@(x).gettype().name
but I don't want to have to do that. I want the function to reliably return an array each time.
The answers to an earlier draft of this question advised me to use the unary operator which worked a treat except that when I pipe the result to ConvertTo-Json (which is ultimately what I need to do) then i do't get the desired result. Observe:
function x()
{
$levelMappings = @()
$levelMappings += @{"a"="b";"c"="d"}
$levelMappings += @{"e"="f";"g"="h"}
return ,$levelMappings
}
(x).gettype().name
x | ConvertTo-Json
Upon running it the result is:
{
"value": [
{
"c": "d",
"a": "b"
},
{
"g": "h",
"e": "f"
}
],
"Count": 2
}
As you can see the object i'm serialising to JSON has been wrapped inside a JSON object called value
and I now have a count
object in there too. This isn't what I want. Any way to solve this?
Another update. I've discovered I can wrap the call to the function in parentheses and it seems to solve it.
function x()
{
$levelMappings = @()
$levelMappings += @{"a"="b";"c"="d"}
$levelMappings += @{"e"="f";"g"="h"}
return ,$levelMappings
}
(x).gettype().name
(x) | ConvertTo-Json
it returns
[
{
"c": "d",
"a": "b"
},
{
"g": "h",
"e": "f"
}
]
Its not ideal...but it does work.
Third update, no, that doesn't work. If its a 1-element array I'm back to the original problem:
function x()
{
$levelMappings = @()
$levelMappings += @{"a"="b"}
return ,$levelMappings
}
(x).gettype().name
(x) | ConvertTo-Json
gives:
{
"a": "b"
}
I give up!!!
Fourth update...
Oh and if I chuck the returned value into a hashtable and convert that to json:
function x()
{
$levelMappings = @()
$levelMappings += @{"a"="b"}
return ,$levelMappings
}
$hashtable = @{}
$hashtable.Add('somekey',(x))
$hashtable | ConvertTo-Json
it appears as a single-element JSON array!
{
"somekey": [
{
"a": "b"
}
]
}
Arrghh!!! :)