在 PowerShell 中返回具有单个元素的数组

Posted

技术标签:

【中文标题】在 PowerShell 中返回具有单个元素的数组【英文标题】:Return array with single element in PowerShell 【发布时间】:2017-06-19 06:34:00 【问题描述】:

这应该很简单——我需要从一个函数返回一个哈希表数组。这在有多个哈希表时有效,但当只有一个时,结果不是数组。我宁愿不测试结果是否为数组。

function GetArrayWith1Hashtable()

    $array = @()

    $hashtable = @
    $hashtable["a"] = "a" 
    $hashtable["b"] = "b" 
    $hashtable["c"] = "c"
    $array += $hashtable 

    Write-Host "GetArrayWith1Hashtable array.Length =" $array.Length
    Write-Host "GetArrayWith1Hashtable array.Count" $array.Count
    Write-Host "GetArrayWith1Hashtable array[0].Keys" $array[0].Keys

    $array


function GetArrayWith2Hashtables()

    $array = @()

    $hashtable = @
    $hashtable["a"] = "a" 
    $hashtable["b"] = "b" 
    $hashtable["c"] = "c"
    $array += $hashtable 

    $hashtable2 = @
    $hashtable2["d"] = "d" 
    $hashtable2["e"] = "e"
    $hashtable2["f"] = "f"
    $array += $hashtable2 

    Write-Host "GetArrayWith2Hashtables array.Length = " $array.Length
    Write-Host "GetArrayWith2Hashtables array.Count = " $array.Count
    Write-Host "GetArrayWith2Hashtables array[0].Keys =" $array[0].Keys
    Write-Host "GetArrayWith2Hashtables array.Count = "$array[1].Keys

    $array


$result1 = GetArrayWith1Hashtable
# $result1.Length - not available
Write-Host "Result of GetArrayWith1Hashtable result1.Count = " $result1.Count                      # Count = 2 (would expect this to be 1)
# $result1[0] not available - not an array

$result2 = GetArrayWith2Hashtables
Write-Host "Result of GetArrayWith2Hashtables result2.Length = "    $result2.Length # Length = 2
Write-Host "Result of GetArrayWith2Hashtables result2.Count = "     $result2.Count # Count = 2
Write-Host "Result of GetArrayWith2Hashtables result2[0].Keys = "     $result2[0].Keys # Keys = c a b
Write-Host "Result of GetArrayWith2Hashtables result2[1].Keys = "     $result2[1].Keys # Keys = d e f

 <#
  FULL OUTPUT:

 GetArrayWith1Hashtable array.Length = 1
 GetArrayWith1Hashtable array.Count 1
 GetArrayWith1Hashtable array[0].Keys c a b

 Result of GetArrayWith1Hashtable result1.Count =  2

 GetArrayWith2Hashtables array.Length =  2
 GetArrayWith2Hashtables array.Count =  2
 GetArrayWith2Hashtables array[0].Keys = c a b
 GetArrayWith2Hashtables array.Count =  d e f

 Result of GetArrayWith2Hashtables result2.Length =  2
 Result of GetArrayWith2Hashtables result2.Count =  2
 Result of GetArrayWith2Hashtables result2[0].Keys =  c a b
 Result of GetArrayWith2Hashtables result2[1].Keys =  d e f

 #>

【问题讨论】:

【参考方案1】:

只需将返回类型转换为数组即可:

$result1 = @(GetArrayWith1Hashtable)

【讨论】:

这不是强制转换,这不是您转换为类型的方式。您在这里所做的是将结果添加到一个全新的数组中,可能会将一个数组添加到一个数组中。 确实不是演员,@JohnC,而是@() 的应用程序array-subexpression operator。但是,对于一个函数一个一个地发出其输出对象的方法来说,它是一个有效的解决方案,正如问题中那样,凭借 PowerShell 对输出对象的自动枚举。可以说让 调用者 确保某物是一个数组会更好,如此处所示,因为发出数组作为单个对象 的函数在管道中不会按预期工作。 @mklement0 你假设太多了。并非所有编写的函数都旨在通过管道传输。 op 想要将数组作为单个对象返回。正如我已经明确指出的那样,这个示例可能会在数组中返回一个数组。如果他们要遵循您所指的与管道一起正常工作的内容,那么所有这些示例都是不正确的,它们应该只为每个项目调用 write-object 而不是一次全部返回一个数组。 @JohnC:是的,它可以在数组中返回一个数组;也就是说,如果您编写的函数表现出非标准行为(将数组作为单个对象返回)。如果这是您的意图,那么您的解决方案会更好 - 然后就不需要 also 使用@()。是的,从技术上讲,这个答案并不完全符合 OP 的要求,但从总体上看,最好避免非标准行为;使用原始函数定义的另一个简单解决方案是使用 [array] $result1 = GetArrayWith1Hashtable @mklement0 没有标准说明您必须从函数返回什么。并非所有函数都设计为在管道中使用。【参考方案2】:

实际上,您只需在退回的商品前添加一个逗号,就像这样。这告诉 PowerShell 按原样返回它,而不是试图对它变得聪明。这还允许您在一个地方修复它,而不是在调用它的任何地方。

function GetArrayWith1Hashtable()

    $array = @()

    $hashtable = @
    $hashtable["a"] = "a" 
    $hashtable["b"] = "b" 
    $hashtable["c"] = "c"
    $array += $hashtable 

    Write-Host "GetArrayWith1Hashtable array.Length =" $array.Length
    Write-Host "GetArrayWith1Hashtable array.Count" $array.Count
    Write-Host "GetArrayWith1Hashtable array[0].Keys" $array[0].Keys

    # The only edit was to add the comma below
    ,$array

更新:虽然我不认为你想要这个功能,但我还是会提到它,以便其他人了解差异并为他们的方法做出明智的选择。

为了让您的函数兼容以便在管道中更有效地使用,更好的方法是为每个项目调用 Write-Object。

function GetArrayWith1Hashtable()

    Write-Object "a" 
    Write-Object "b" 
    Write-Object "c"

通过使用 Write-Object,您允许 PowerShell 分别为每个对象调用管道中下一个命令的 Process block。否则它将调用下一个命令并将单个数组对象传递给它。你可以阅读更多关于piping objects here

【讨论】:

赞成这个答案,因为虽然接受的答案有效,但这个答案更干净地解决了问题,调用代码不需要任何修改。 没错,@PhilChuang,调用者不需要修改,但另一方面,将数组作为单个对象发出的函数在管道中无法按预期工作。 @mklement0 正如我在对您的其他回复中所说的那样,您假设很多并且没有回答操作员的要求。并非所有函数都打算在管道中使用。 @JohnC:正如对另一个答案的评论中所述,您的回答为 as ask 问题提供了解决方案(这就是我赞成它的原因),但非常您刚刚提出的观点值得成为您答案的一部分:对于预计不会在管道中使用的简单辅助函数,可以使用这种方法。有了这些知识,读者就可以决定哪种方法适合他们。 “Write-Object”一词未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。

以上是关于在 PowerShell 中返回具有单个元素的数组的主要内容,如果未能解决你的问题,请参考以下文章

Elm:将具有单个元素的 JSON 数组解码为字符串

在单个 MySQL 查询中,我可以从具有主键数组的字段返回字符串数组吗

Powershell数组被解释为单个项目

PowerShell,从变量中提取多个数组以生成单个变量

使用 Pymongo 更新具有匹配 id 和数组元素之一的单个数组项

将字符串数组的所有元素写入单个字符串