考虑以下代码:
$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
具体的吗?喜欢bug / issue?
答案 0 :(得分:0)
关于管道项目的展开只有一个规则:写入管道的所有数组和集合总是被解包到项目(“展开一层”或“以非递归方式解包” “这将是更正确的陈述,但为了简单起见,到目前为止我们不会考虑嵌套数组。”
使用一元逗号运算符仍有可能覆盖此行为:
$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