Добавить массив объектов в PSObject сразу - PullRequest
0 голосов
/ 30 ноября 2018

Я хочу программно объединить данные 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 преобразует значение PSObject в строку, а не принимает ее как есть.

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

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

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

Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

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

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

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

Устранение обеих проблем приводит к:

# 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 | ForEach-Object { 
  $_ | Add-Member -MemberType NoteProperty -Name 'Detail' -Value $detail -PassThru
} | ConvertTo-Json -Depth 3  # Note the required -Depth value.

[1] Возможно, к удивлению, -Depth по умолчанию равен 2, что является частой ошибкой для пользователей - см. этот вопрос .

0 голосов
/ 30 ноября 2018

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

$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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...