从函数返回单个对象作为数组

时间:2016-03-18 15:09:06

标签: powershell

我在PowerShell中遇到一个问题,即从函数返回的1元素数组不会作为数组返回。我发现有很多地方提出了类似的问题(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?),但那里的解决方案对我不起作用。 这是我的代码:

function x()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b";"c"="d"}
    return @($levelMappings) 
}
(x).gettype().name

返回

  

哈希表

我不希望这样,我希望返回的东西总是一个数组,即使它只有一个元素。我知道我可以通过显式将函数的返回值转换为数组来解决这个问题:

function x()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b";"c"="d"}
    return @($levelMappings) 
}
@(x).gettype().name

但我不想这样做。我希望函数每次都可靠地返回一个数组。

这个问题的早期草案的答案建议我使用一元运算符,它处理除了,当我将结果传递给ConvertTo-Json时(这最终是我需要做的) )然后我没有得到理想的结果。观察:

function x()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b";"c"="d"}
    $levelMappings += @{"e"="f";"g"="h"}
    return ,$levelMappings
}
(x).gettype().name
x | ConvertTo-Json

运行后,结果为:

  

{
      “价值”:[
                    {
                        “c”:“d”,
                        “a”:“b”
                    },
                    {
                        “g”:“h”,
                        “e”:“f”
                    }
                ],
      “伯爵”:2   }

正如您所看到的,我正在序列化为JSON的对象已被包装在名为value的JSON对象中,我现在也有一个count对象。这不是我想要的。有什么方法可以解决这个问题吗?

另一个更新。我发现我可以在括号中包含对函数的调用,它似乎可以解决它。

function x()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b";"c"="d"}
    $levelMappings += @{"e"="f";"g"="h"}
    return ,$levelMappings
}
(x).gettype().name
(x) | ConvertTo-Json

它返回

  

[
      {
          “c”:“d”,
          “a”:“b”
      },
      {
          “g”:“h”,
          “e”:“f”
      }
  ]

它不理想......但确实有效。

第三次更新,不,这不起作用。如果它是一个1元素的数组我回到原来的问题:

function x()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b"}
    return ,$levelMappings
}
(x).gettype().name
(x) | ConvertTo-Json

给出:

  

{
      “a”:“b”
  }

我放弃!!!

第四次更新......

哦,如果我将返回的值放入哈希表并将其转换为json:

function x()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b"}
    return ,$levelMappings
}
$hashtable = @{}
$hashtable.Add('somekey',(x))
$hashtable | ConvertTo-Json

它显示为单元素JSON数组!

  

{
      “somekey”:[
                      {
                          “a”:“b”
                      }
                  ]
  }

Arrghh !!! :)

4 个答案:

答案 0 :(得分:2)

试试这个:

function x()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b";"c"="d"}
    return ,$levelMappings
}
(x).gettype().name

一元逗号运算符用于指示PowerShell将对象包装在其后面,这将使对象成为数组,而不是返回时的哈希表。

答案 1 :(得分:1)

Powershell喜欢在任何地方展开数组。

您可以通过将返回行更改为此来强制执行您想要的操作:

return , $levelmappings

它会弹出一个阵列。

答案 2 :(得分:0)

最终答案,一个不会导致ConvertTo-Json混淆结果的答案

function x()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b";"c"="d"}
    $levelMappings += @{"e"="f";"g"="h"}
    return ,$levelMappings
}
(x).gettype().name
(x) | ConvertTo-Json

答案 3 :(得分:0)

有时候管道是你的朋友,有时候你应该把你的代码分成几部分并且是有意的,这也有助于提高可读性,或者当其他人阅读你的代码时。

我搜索" powershell convertto-json force json array" ,第一次点击是:ConvertTo-JSON an array with a single item,Ansgar Wiechers在那里发布了一个优雅的答案,所以也许这是重复的。我想这取决于这个问题是否真的与强制函数返回一个数组有关。 (问题)或者是否真的"强制ConvertTo-Json始终创建一个数组" (问题)

无论如何,我相信以下内容完成了所有OP愿望:

<强>代码:

function x1()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b"}
    return $levelMappings
}
"X1: " + (x1).gettype().name
ConvertTo-Json @(x1)

function x2()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b";"c"="d"}
    return $levelMappings
}
"X2: " + (x1).gettype().name
ConvertTo-Json @(x2)

function x3()
{
    $levelMappings = @()
    $levelMappings += @{"a"="b";"c"="d"}
    $levelMappings += @{"e"="f";"g"="h"}
    return $levelMappings
}
"X3: " + (x1).gettype().name
ConvertTo-Json @(x3)

<强>输出:

X1: Hashtable
[
    {
        "a":  "b"
    }
]
X2: Hashtable
[
    {
        "c":  "d",
        "a":  "b"
    }
]
X3: Hashtable
[
    {
        "c":  "d",
        "a":  "b"
    },
    {
        "g":  "h",
        "e":  "f"
    }
]