1

我正在调用一个 API,它在对象“tags”中返回 3 个值,该对象具有“tags.name”和 tags.results“的值。下面的值是返回的值。但是当我尝试浏览这些值时,我可以看到“null”值 {} 没有存储在数组中。它只是跳过了它,但我需要这个值,因为它完全破坏了数组。

知道如何正确填充数组以使其不会跳过此 {} 值吗?

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。您可以看到第二个节点的返回值为 null 的位置。

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

4

1 回答 1

0

该问题并非特定于PowerShell 的成员枚举功能的行为,Invoke-RestMethod而是由其解释:

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

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

这样做,空数组被有效从输出中删除,并且您只得到2 个输出对象(在您的情况下,每个都包含嵌套对象的内部数组);(...).Count您可以通过应用上面的命令来验证这一点。

原因是脚本块( { ... }) 输出的对象被发送到管道,管道默认枚举作为集合(数组)的对象。
由于您的第二个.values值是一个数组(从 JSON 解析[],因此不是 $null),因此没有任何可枚举的内容,也没有任何输出,从而导致有效删除。

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


解决方法是使用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-Objectcmdlet;但是,或者,您可以通过使用数组构造函数运算符的一元形式将脚本块输出包装在保留原始数组的辅助临时单元素数组中来解决此问题:也 可以使用与- 较慢 - cmdlet,
.ForEach({ , $_.values })
ForEach-Object

于 2020-11-16T22:00:40.927 回答