What are the rules for automatically packing or unpacking arrays?

Consider this code:

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

This leads to the following conclusion:

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

Obviously, if we use a temporary variable, what is piped is not the same as what is transmitted if we do not use it.

I would like to know what are the rules that powershell uses to automatically wrap / unpack arrays, and if using temp var is the best way to go, if we need to iterate through a json array.

Update 1 Logically, ConvertFrom-Json should return an array with the specified input, and ForEach-Object should be repeated over the specified array. However, this does not happen in the first test. What for? Update 2 Is it possible that it is ConvertFrom-Json specific? How is the error / problem?

+5
source share
1 answer

There is only one rule regarding the expansion of pipeline elements: all arrays and collections written in the pipeline always expand to the elements (“expanded one level down” or “expanded in a non-recursive manner” will be a more correct statement, but for simplicity we will not consider nested arrays).

There is still the option to override this behavior using the unary comma operator:

 $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 

In the second case, the Powershell pipeline engine expanded $a , but then the result was returned to the array by the operator,.

Regarding the ConvertFrom-Json , I personally believe that its observed behavior is more predictable, since it allows us to collect JSON arrays in general by default. If you are interested in the details, the Get-WrappedArray in the code below mimics the behavior of 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 
0
source

Source: https://habr.com/ru/post/1270946/


All Articles