Добавить массив объектов в 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