Powershell — развернуть подмассив и переименовать поля

#powershell

#powershell

Вопрос:

У меня есть исходный массив, подобный этому

 $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" } ) 
   }
)
  

Мне нужно извлечь отношения между родительским и дочерним массивами следующим образом:

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

Я придумал следующий код для достижения этой цели

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

Интересно, есть ли какое-то более прямое решение.

Редактировать:

На основе ответа Marsze — слегка измененное решение

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

Ответ №1:

Для меня это выглядит довольно просто. foreach Вместо командлета конвейера можно использовать циклы, что быстрее и имеет то преимущество, что вы можете напрямую ссылаться на переменные на каждом уровне.

Также я рекомендовал преобразовать в PSCustomObject для правильного выходного формата:

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

В качестве альтернативы с New-Object :

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

Или Select-Object версию:

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