自动数组包装/解包的规则是什么?

And*_*ykh 5 powershell

考虑以下代码:

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

这会产生以下输出:

Test1

IsPublic IsSerial Name                                     BaseType                                                                                                                           
-------- -------- ----                                     --------                                                                                                                           
True     True     Object[]                                 System.Array                                                                                                                       
Test2
True     False    PSCustomObject                           System.Object                                                                                                                      
True     False    PSCustomObject                           System.Object  
Run Code Online (Sandbox Code Playgroud)

显然,如果我们使用临时变量,那么传递给管道的任何东西与我们不使用它时传递的东西不同.

我想知道powershell用于自动数组包装/解包的规则是什么,如果我们需要迭代json数组,如果使用temp var是最好的操作方法.

更新1 逻辑上ConvertFrom-Json应该返回一个给定输入的数组,并且ForEach-Object应该在所述数组上迭代.然而,在第一次测试中,这不会发生.为什么? 更新2 它是否可能ConvertFrom-Json具体?喜欢bug /问题?

mao*_*izm 1

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

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

$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
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,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
Run Code Online (Sandbox Code Playgroud)