自动阵列包装/解包的规则是什么?



请考虑以下代码:

$a = '[{"a":"b"},{"c":"d"}]'
"Test1"
$a | ConvertFrom-Json | ForEach-Object { $_.GetType() }
"Test2"
$b = $a | ConvertFrom-Json
$b | ForEach-Object { $_.GetType() }

这将生成以下输出:

Test1
IsPublic IsSerial Name                                     BaseType                                                                                                                           
-------- -------- ----                                     --------                                                                                                                           
True     True     Object[]                                 System.Array                                                                                                                       
Test2
True     False    PSCustomObject                           System.Object                                                                                                                      
True     False    PSCustomObject                           System.Object  

显然,如果我们使用临时变量,那么从管道中传递的任何内容都与不使用临时变量时传递的内容不同。

我想知道 powershell 用于自动数组包装/解包的规则是什么,以及如果我们需要遍历 json 数组,使用 temp var 是最佳行动方案。

更新 1逻辑上ConvertFrom-Json应该返回一个数组,其中包含给定的输入,ForEach-Object应该迭代该数组。但是,在第一次测试中,这不会发生。为什么?更新 2有没有可能ConvertFrom-Json具体?喜欢错误/问题?

关于管道项目的解包只有一条规则:写入管道的所有数组和集合总是被解包到项目("向下解包一层"或"以非递归方式解包"会更正确的说法,但为了简单起见,到目前为止我们不打算考虑嵌套数组(。

仍然有可能通过使用一元逗号运算符来覆盖此行为:

$a = 1,2
$a | ForEach-Object{ $_.GetType() }
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType
True     True     Int32                                    System.ValueType
,$a | ForEach-Object{ $_.GetType() }
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

在第二种情况下,Powershell 管道引擎解开了$a但之后结果作员包装回,数组。

至于ConvertFrom-Json情况,我个人认为其观察到的行为更具可预测性,因为它允许您默认捕获整个 JSON 数组。 如果您对细节感兴趣,下面代码中Get-WrappedArray的函数模仿ConvertFrom-Json的行为:

function Get-WrappedArray {
Begin   { $result = @() } 
Process { $result += $_ } 
End     { ,$result }
}
$a | Get-WrappedArray | ForEach-Object{ $_.GetType() }
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
$b = $a | Get-WrappedArray
$b | ForEach-Object{ $_.GetType() }
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType
True     True     Int32                                    System.ValueType

最新更新