【问题标题】:return a single object from a function as an array从函数返回单个对象作为数组
【发布时间】:2016-03-18 15:09:06
【问题描述】:

我在 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 时(这最终是我需要做的)except ) 那么我没有得到想要的结果。观察:

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 数组!

{
“一些关键”:[
{
"a": "b"
}
]
}

啊!!! :)

【问题讨论】:

标签: powershell


【解决方案1】:

试试这个:

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

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

【讨论】:

  • 嘿,你打败了我,而且用更好的措辞回答。
  • 它不会像将数组包装在 another 数组中那样“使其成为数组”,以便 powershell 展开 that 数组而不是你的。基本上,您正在为 powershell 创建一个一次性数组,而不是您的 real 数组。
  • 所有,我在发送到ConvertTo-Json 时遇到了问题,并相应地编辑了问题。你介意看看吗?
  • 没关系,想通了,已经编辑了问题并相应地发布了答案。
【解决方案2】:

Powershell 喜欢尽可能展开数组。

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

return , $levelmappings

它会以数组的形式弹出。

【讨论】:

    【解决方案3】:

    最终答案,不会导致ConvertTo-Json 弄乱结果

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

    【讨论】:

    • 刚刚意识到如果数组只有一个元素是行不通的,因为 PowerShell 会再次打开它!叹!所以我回到了我开始的地方!!我放弃了:)
    • 考虑重构您的代码以不使用管道,也许您的问题可以得到解决,并为您的代码中的其他地方留下改进的模式。
    【解决方案4】:

    有时管道是您的朋友,有时您应该将代码分成几部分并有意为之,这也有助于提高未来或其他人阅读您的代码时的可读性。

    我搜索了 “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"
        }
    ]
    

    【讨论】:

      猜你喜欢
      • 2018-01-25
      • 2020-07-20
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      相关资源
      最近更新 更多