Skip to content

ConvertFrom-Json sends objects converted from a JSON array as an *array* through the pipeline. #3424

@mklement0

Description

@mklement0

Note: Perhaps the behavior in question will rarely be noticed as problematic in the real world, so perhaps the only thing that's needed is adding a note to the documentation - I'm unclear on whether this ultimately a non-issue.

alpha.17 fixed issue #3153 with respect to ConvertTo-Json no longer wrapping ConvertFrom-Json array output in an extraneous object with value and count properties.

However, ConvertFrom-Json still sends the objects resulting from converting a JSON array as a single array through the pipeline, which is a deviation from the usual cmdlet behavior of unwrapping collections and sending the items one by one.

> ('[ 1, 2 ]' | ConvertFrom-Json | Measure-Object).Count
1  # !! PS array `1, 2` was sent as a *single* object through the pipeline.

Workaround: Enclose the ConvertFrom-Json part of the pipeline in (...), which forces enumeration:

> (('[ 1, 2 ]' | ConvertFrom-Json) | Measure-Object).Count
2  # OK, (...) forced enumeration

Alternatively, simply insert a Write-Output pipeline segment:

> ('[ 1, 2 ]' | ConvertFrom-Json | Write-Output | Measure-Object).Count
2  # OK, Write-Output forced enumeration

Note: On Windows PowerShell, as of v5.1, you paradoxically need Write-Output -NoEnumerate to prevent unwrapping from getting applied to the individual array elements as well.

On the plus side, as @PetSerAl points out, this preserves the input structure in a round-trip in the case of single-element JSON arrays:

> '[ 1 ]' | ConvertFrom-Json | ConvertTo-Json
[
  1
]

It is only ConvertFrom-Json's send-the-array-as-a-whole approach that enables the above round trip.

By contrast, when you start with a PS array, it doesn't work that way (which illustrates the difference in pipeline behavior):

> , 1 | ConvertTo-Json
1 # !! Input PS array was unwrapped on sending it through the pipeline

To preserve the array, you must explicitly nest the array:

> , , 1 | ConvertTo-Json
[
  1
]

# Alternative: explicitly prevent enumeration
> Write-Output -NoEnumerate (, 1) | ConvertTo-Json
[
  1
]

Environment data

PowerShell Core v6.0.0-alpha (v6.0.0-alpha.17) on Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64

Metadata

Metadata

Assignees

No one assigned

    Labels

    Committee-ReviewedPS-Committee has reviewed this and made a decisionResolution-FixedThe issue is fixed.WG-Cmdlets-Utilitycmdlets in the Microsoft.PowerShell.Utility module

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions