Powershell - Expand subArray and rename fields

Viewed 197

I have a source array like this

$myArray = (
   @{ id = "1"; name = "first item"; 
       subArray = (
           @{ id = "A"; name = "first subitem" }, 
           @{ id = "B"; name = "second subitem" } ) 
   },
   @{ id = "2"; name = "second item"; 
       subArray = (
           @{ id = "C"; name = "third subitem" }, 
           @{ id = "D"; name = "fourth subitem" } ) 
   }
)

I need to extract the relations between the parent and child arrays like following:

source     target
-----------------
1           A
1           B
2           C
2           D

I have come up with a following code to achieve that

$myArray | ForEach-Object {
    $id = $_.id
    $_.subArray | ForEach-Object { 
        @{
            source = $id
            target = $_.id
        } 
    }
}

I wonder if there is some more straight forward solution.

Edit:

Based on Marsze answer - slightly modified solution

$myArray| ForEach-Object  
    {$a=$_; $a.subArray | Select-Object @{n="source";e={$a.id}},@{n="target";e={$_.id}}
}
1 Answers

Looks pretty straightforward to me. You could use foreach loops instead of the pipeline cmdlet, which is faster and has the advantage, that you can reference variables on each level directly.

Also I recommended converting to PSCustomObject for the proper output format:

foreach ($a in $myArray) {
    foreach ($b in $a.subArray) {
        [PSCustomObject]@{source = $a.id; target = $b.id}
    }
}

Alternatively with New-Object:

foreach ($a in $myArray) {
    foreach ($b in $a.subArray) {
        New-Object PSObject -Property @{source = $a.id; target = $b.id}
    }
}

Or the Select-Object version:

foreach ($a in $myArray) {
    $a.subArray | select @{n="source";e={$a.id}},@{n="target";e={$_.id}}
}
Related