PowerShell Invoke-RestMethod пропускает возвращаемое нулевое значение при навигации по значениям массива. Идеи?
Я вызываю API, который возвращает 3 значения в объекте "tags", который имеет значения для "tags.name" и tags.results ". Возвращаются значения, указанные ниже. Но когда я пытаюсь перемещаться по значениям, я можно увидеть, что "нулевое" значение, {}, не было сохранено в массиве. Он просто пропустил его, но мне нужно это значение, поскольку оно полностью разрушает массив.
Есть идеи, как правильно заполнить массив, чтобы он не пропустил это значение {}?
Response Values
values attributes
------ ----------
{1605560351000 78.129448 3} @{machine_type=System.Object[]}
{}
{1605560354000 0 3} @{machine_type=System.Object[]}
Resulting Array
0 : 1605560351000 78.129448 3
1 : 1605560354000 0 3
2 :
Код nvoke и массива PowerShell:
$response = Invoke-RestMethod 'https://api' -Method 'POST' -Headers $headers -Body $body
"Response Values"
$response.tags.results
""
"Resulting Array"
"0 : " + $response.tags.results.values[0]
"1 : " + $response.tags.results.values[1]
"2 : " + $response.tags.results.values[2]
Возвращенный JSON из Invoke-RestAPI. Вы можете увидеть, где возвращенное значение для второго узла является нулевым.
{
"tags": [
{
"name": "StateComp1",
"results": [
{
"values": [
[
1605561152000,
75.436455,
3
]
],
}
],
},
{
"name": "StateComp2",
"results": [
{
"values": [],
}
],
},
{
"name": "StateComp3",
"results": [
{
"values": [
[
1605561469000,
0,
3
]
],
}
],
}
]
}
1 ответ
Проблема не связана с Invoke-RestMethod
и вместо того, чтобы объяснить поведение PowerShell в элемент перечисления функции:
Когда вы получаете доступ
$response.tags.results.values
, то
.values
свойства на - несколько -
.results
свойства (вы используете вложенное перечисление членов) эффективно перечисляются следующим образом:
$response.tags.results | ForEach-Object { $_.values }
При этом пустые массивы эффективно удаляются из вывода, и вы получаете только 2 объекта вывода (каждый из которых содержит внутренний массив вложенных в вашем случае); вы можете проверить это, применив
(...).Count
к команде выше.
Причина в том, что объекты, выводимые блоком скрипта ({ ... }
) отправляются в конвейер, который по умолчанию перечисляет объекты, являющиеся коллекциями (массивами).
С вашего 2-го
.values
value - пустой массив (полученный из JSON
[]
и поэтому не
$null
), нечего перечислять и ничего не выводится, что приводит к эффективному удалению.
Обратите внимание, что вышесказанное подразумевает, что коллекции коллекций сглаживаются перечислением членов; например, если значения свойств представляют собой 3 массива из 2 элементов, логика конвейерного перечисления приводит к единственному массиву из 6 элементов, а не к массиву из 3 элементов, каждый из которых содержит массивы из 2 элементов.
Обходной путь является использовать ForEach()
массив метод, который не выполняет этой зачистки, если вы нацелены на имущество путем подачи его имя в качестве строки:
$values = $response.tags.results.ForEach('values')
@"
Resulting Array"
0 : $($values[0])
1 : $($values[1])
2 : $($values[2])
"@
Обратите внимание, что ваш непустой
.values
свойства фактически являются вложенными массивами; чтобы избавиться от внешнего массива, используйте
$values[0][0]
,
$values[1][0]
, и
$values[2][0]
.
Предостережение: обходной путь эффективен только в том случае, если вы получаете доступ к свойству по строке имени -
.ForEach('values')
; кажущаяся эквивалентной команда на основе блока сценария,
.ForEach({ $_.values })
снова удаляет пустые массивы, такие как перечисление членов и
ForEach-Object
командлет; в качестве альтернативы, однако, вы можете обойти это, заключив вывод блока сценария во вспомогательный, временный одноэлементный массив, который сохраняет исходные массивы, используя унарную форму
,
оператор конструктор массива:
.ForEach({ , $_.values })
Вы также можете использовать ту же технику с - медленнее -
ForEach-Object
командлет.