1

Given the following JSON

[
  {
    "key": "James",
    "things": [
      {
        "id": 123,
        "name": "PRD"
      },
      {
        "id": 124,
        "name": "PRE"
      }
    ]
  },
  {
    "key": "Susan",
    "things": [
      {
        "id": 125,
        "name": "PRF"
      },
      {
        "id": 126,
        "name": "PRG"
      }
    ]
  }
]

Which, I've easily converted into a Powershell object:

$json = '[{"key":"James", "things":[{"id":123,"name":"PRD"},{"id":124,"name":"PRE"}]},{"key":"Susan", "things":[{"id":125,"name":"PRF"},{"id":126,"name":"PRG"}]}]'

$obj = $json | ConvertFrom-Json 

How do I flatten the sub-array things and include the key from the parent object, so that my result set is

key    id name
---    -- ----
James 123 PRD  
James 124 PRE  
Susan 125 PRF
Susan 126 PRG

I've used the following to flatten the sub-array:

$obj | % { $_.things}  

Which returns me

 id name
 -- ----
123 PRD  
124 PRE  
125 PRF
126 PRG

But, I can't quite figure out what to do next.

Any help would be much appreciated.

1
  • 1
    FYI, in case you didn't knew $obj | % { $_.things} can be replaced by $obj.things . Powershell will do its thing, enumarate the things and produce the same output in either cases. Commented Nov 26, 2021 at 9:55

2 Answers 2

2

You loop into each key, then loop into each things, since you want 1 result per thing, and build a PSObject using the current key, id and name.

Here you go.

# initial code sample
$json = '[{"key":"James", "things":[{"id":123,"name":"PRD"},{"id":124,"name":"PRE"}]},{"key":"Susan", "things":[{"id":125,"name":"PRF"},{"id":126,"name":"PRG"}]}]'
$obj = $json | ConvertFrom-Json 

# Loop needed to flatten the object.
foreach ($i in $obj) {
    foreach ($t in $i.things) {
        [PSCustomObject]@{
            key  = $i.key
            id   = $t.id
            name = $t.name
        }
    }
}

Output

key    id name
---    -- ----
James 123 PRD
James 124 PRE
Susan 125 PRF
Susan 126 PRG
Sign up to request clarification or add additional context in comments.

3 Comments

Hmmmm "Cannot convert value to type "System.Management.Automation.LanguagePrimitives+InternalPSCustomObject". Only core types are supported in this language mode."
@JamesWiseman That is because you are working in constrained mode. As far as I know, this mode is very limited in what you can do. You might be able to do a pipeldouble pipeline for each with the use of pipeline variable and produce your output through a select statement that use a calculated property for the key... Not sure if calculated properties work in constrained mode though. I'll check when I am back in front of the PC.
Turns out it was my local windows security policy. Running the Script in Powershell ISE with elevated 'Admin' privs fixed this. Interesting thought experiment though, achieving this with more primitive powershell.
1

you can use built-in flattening with select as follows:

($json | ConvertFrom-Json) | Select-Object key -ExpandProperty things

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.