当仅存在一个元素时,不规则的PowerShell数组会丢失一个维度

11
我有以下的PowerShell函数,对于除了1之外的任何输入都能很好地运行。但是如果我传递一个1的输入,它将返回一个包含两个元素1,1的数组,而不是一个单独的元素,它本身是一个由两个元素(1,1)组成的数组。
有什么想法可以让PowerShell返回一个包含一个元素的嵌套数组?
function getFactorPairs {
    param($n)
    $factorPairs = @()
    $maxDiv = [math]::sqrt($n)
    write-verbose "Max Divisor: $maxDiv"
    for($c = 1; $c -le $maxDiv; $c ++) {
        $o = $n / $c;
        if($o -eq [math]::floor($o)) {
            write-debug "Factor Pair: $c, $o"
            $factorPairs += ,@($c,$o) # comma tells powershell to add defined array as element in existing array instead of adding array elements to existing array
        }
    }
    return $factorPairs
}

这是我的测试和输出,显示了问题。您可以看到第一个示例(输入为1)返回长度为2,尽管只找到了一个因子对。第二个示例(输入为6)正常工作,并返回长度为2,找到了两个因子对。

~» (getFactorPairs 1).length  
   DEBUG: Factor Pair: 1, 1  
   2  

~» (getFactorPairs 6).length  
   DEBUG: Factor Pair: 1, 6  
   DEBUG: Factor Pair: 2, 3  
   2  
2个回答

15

我在Windows XP上的PowerShell V2 CTP上进行了测试,并看到了与OP相同的结果。

问题似乎是PowerShell在沿着管道传递集合时“展平”它们的习惯。一个简单的解决方案是通过在要返回的表达式前加逗号运算符来将返回值包装在集合中,如下:

return ,$factorPairs

有关更多详细信息,请参阅Keith Hill的博客文章 Effective PowerShell Item 8: Output Cardinality - Scalars, Collections and Empty Sets - Oh My!

希望这可以帮助到您。


很棒的解决方法和链接,看起来这个 bug 已经被修复了(https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=281908&SiteID=99),可能是在 PowerShell v3 中。 - Francis Norton

6

你很接近了。你遇到的问题是PowerShell在从函数返回数组时会展开(扁平化)它。使用逗号运算符可以将数组原样返回而不展开它:

return ,$factorPairs

当数组中只有一个元素时,对于输入1、2、3和其他质数的情况,PowerShell会将数组的内容展开到输出中,因此每个元素(1,1)都会出现在输出中。为什么PowerShell在这种情况下展开外部和内部数组——我不确定。我猜他们这样做是因为有些人会期望PowerShell表现出这种行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接