Добавить массив объектов в PSObject сразу

Я хочу соединить программно данные JSON от мастера и список деталей. Упрощенный пример моего кода будет:

$master = '[{"Sample": 1.3085},{"Sample":  1.4567}]' | ConvertFrom-Json
$detail = '[{"foo":1, "bar":2},{"foo":3, "bar":4}]' | ConvertFrom-Json

$master  | %{ 
    $_ | Add-Member -MemberType NoteProperty -Name 'Detail' -Value $detail -PassThru
} | ConvertTo-Json  

Я ожидаю этого:

[{
        "Sample": 1.3085,
        "Detail": [
                {"foo" :1, "bar":2},
                {"foo" :3, "bar":4}
            ]
        }
    }, {
        "Sample": 1.4567,
        "Detail": [
                {"foo" :1, "bar":2},
                {"foo" :3, "bar":4}
            ]
        }
    }
]

Но я понимаю, что

[{
        "Sample": 1.3085,
        "Detail": {
            "value": [
                "@{foo=1; bar=2}",
                "@{foo=3; bar=4}"
            ],
            "Count": 2
        }
    }, {
        "Sample": 1.4567,
        "Detail": {
            "value": [
                "@{foo=1; bar=2}",
                "@{foo=3; bar=4}"
            ],
            "Count": 2
        }
    }
]

Мне кажется, что Add-Member snippet вместо этого преобразует значение PSObject в строку, не принимая его как есть.

Также: когда массив $ master содержит только один элемент, он работает лучше, хотя и не так, как ожидалось, но если их больше одного, он выполняет приведенный выше строковый результат.

Это результаты с одним единственным элементом в $ master:

{
    "Sample":  1.3085,
    "Detail":  {
                   "value":  [
                                 {
                                     "foo":  1,
                                     "bar":  2
                                 },
                                 {
                                     "foo":  3,
                                     "bar":  4
                                 }
                             ],
                   "Count":  2
               }
}

Что я делаю неправильно?

2 ответа

Есть две проблемы с вашим кодом:

  • Вы столкнулись с ошибкой, все еще присутствующей в Windows PowerShell, но с тех пор исправленной в Powershell Core, которая вызывает нежелательные value а также Count свойства, которые появятся в массивах - см. эту проблему GitHub.

  • Чтобы обеспечить преобразование всей глубины дерева входных объектов в JSON, необходимо увеличить значение по умолчанию. -Depth (по крайней мере) соответствовать фактической глубине.

Решение обеих проблем дает:

# Windows PowerShell workaround for array-serialization bug.
# See https://github.com/PowerShell/PowerShell/issues/3222
Remove-TypeData -ErrorAction Ignore System.Array

$master = '[{"Sample": 1.3085},{"Sample":  1.4567}]' | ConvertFrom-Json
$detail = '[{"foo":1, "bar":2},{"foo":3, "bar":4}]' | ConvertFrom-Json

$master  | %{ 
  $_ | Add-Member -MemberType NoteProperty -Name 'Detail' -Value $detail -PassThru
} | ConvertTo-Json -Depth 3  # Note the required -Depth value.

Хорошо, после того, как я возился с этим некоторое время, это настолько близко, насколько я могу получить.

$master = '[{"Sample":1.3085},{"Sample":1.4567}]'

$detail = '[{"foo":1,"bar":2},{"foo":3,"bar":4}]'

$master = ConvertFrom-Json -InputObject $master
$detail = ConvertFrom-Json -InputObject $detail

$i = 0
$master | % { 

$_ | Add-Member -Name 'Detail' -Value $detail.GetValue($i) -MemberType NoteProperty -PassThru

$i++
} | ConvertTo-Json -Depth 3

При добавлении новых участников в [PSCustomObject]ничто не указывает, куда каждое значение должно идти. Вместо этого он просто добавляет все значения к новому элементу Detail. Я смог обойти это, выполнив цикл foreach, и каждая итерация добавляет 1 к переменной $i

Другие вопросы по тегам