PowerShell Invoke-RestMethod 在浏览数组值时会跳过返回的空值。想法?

PowerShell Invoke-RestMethod skips a returned null value when navigating through the array values. Ideas?

我正在调用对象“标签”中 returns 3 个值的 API,它具有“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 : 

PowerShell nvoke 和数组代码:

    $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]

从 Invoke-RestAPI 返回的 JSON。您可以看到第二个节点的返回值为空。

{
    "tags": [
        {
            "name": "StateComp1",
            "results": [
                {
                    "values": [
                        [
                            1605561152000,
                            75.436455,
                            3
                        ]
                    ],
                }
            ],
        },
        {
            "name": "StateComp2",
            "results": [
                {
                    "values": [],
                }
            ],
        },
        {
            "name": "StateComp3",
            "results": [
                {
                    "values": [
                        [
                            1605561469000,
                            0,
                            3
                        ]
                    ],
                }
            ],
        }
    ]
}

问题并非特定于 Invoke-RestMethod and is instead explained by the behavior of PowerShell's member-access enumeration 功能:

当您访问 $response.tags.results.values 时,- 多个 .results 属性上的 .values 属性(您正在使用 nested 成员-访问枚举)有效枚举如下:

$response.tags.results | ForEach-Object { $_.values }

在这样做时,空数组实际上从输出中删除,并且您仅获取 2 输出对象(每个对象都包含 inner 嵌套对象的数组);您可以通过将 (...).Count 应用于上面的命令来验证。

原因是 script block ({ ... }) 输出的对象被发送到 管道 ,默认情况下 枚举 作为集合(数组)的对象。
由于 你的第二个 .values 值是一个 数组 (从 JSON [] 解析,因此 not $null),没有什么可枚举的,nothing输出,导致有效去除。

请注意,以上暗示集合的集合被成员访问枚举扁平化;例如,如果 属性 值是 3 个 2 元素数组,管道枚举逻辑将生成单个 6 元素数组,而不是每个包含 2 元素数组的 3 元素数组。


解决方法 是使用 ForEach() array method,它不会执行此剥离 if 你的目标是 属性 通过提供其名称作为 string:

$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].

警告:仅当您按名称字符串[访问属性时,解决方法才有效=82=] - .ForEach('values');看似等价的基于 script-block 的命令,
.ForEach({ $_.values }) 再次删除空数组,如成员访问枚举和 ForEach-Object cmdlet; 或者,但是,您可以通过将脚本块输出包装在一个辅助的、临时的单元素数组中来解决这个问题,它保留了原始数组, 使用 , 的一元形式 array constructor operator:
.ForEach({ , $_.values })
您也可以使用相同的技术 - 较慢 - ForEach-Object cmdlet.