Вложенные массивы и ConvertTo-Json

Чтобы использовать REST API, я должен передать объект JSON, который выглядит следующим образом:

{ "series" : 
  [{  
      "metric": "custom.powershell.gauge",
      "points":[[1434684739, 1000]]
    }
  ]
}

Обратите внимание на вложенный массив здесь. Я не могу воспроизвести это. Вот мой код:

[int][double]$unixtime=get-date ( (get-date).ToUniversalTime() ) -UFormat %s
$obj=@{}
$series=@{}
$array=@()
$points=@()
$value=get-random -Minimum 0 -Maximum 100


$series.add("metric","custom.powershell.gauge")
$points=@(@($unixtime, $value))
$series.add("points",$points)
$obj.Add("series",@($series))

$json=$obj | ConvertTo-Json -Depth 30 -Compress
$json

И вот вывод:

{"series":[{"points":[1434685292,95],"metric":"custom.powershell.gauge"}]}

Я перепробовал много вещей, я не могу получить 2 массива для вложения, он всегда выглядит как один массив.

На той же ноте пришел кто-то объяснить это пожалуйста:

> $a=(1,2)
> $a
1
2
> $a | ConvertTo-Json
[
    1,
    2
]
> $b=($a,$a)
> $b
1
2
1
2
> $b | ConvertTo-Json
[
    {
        "value":  [
                      1,
                      2
                  ],
        "Count":  2
    },
    {
        "value":  [
                      1,
                      2
                  ],
        "Count":  2
    }
]

Где эти value а также Count приходящий из?

Спасибо за вашу помощь.

3 ответа

Решение

Объяснение в том, что (1,2),(3,4) является массивом массивов, но Powershell разделил первый уровень с помощью канала |и вы не даете имя для этих массивов, поэтому сериализатор предоставляет его. Сначала попробуйте это:

# First build your array of array
$z = (1,2),(3,4)
# convert it to JSON using the ,
,$z | ConvertTo-Json -Depth 5 -Compress
[psobject]@{"points"=$z} | ConvertTo-Json -Depth 5 -Compress

Это дает первый шаг:

{"value":[[1,2],[3,4]],"Count":2}
{"points":[[1,2],[3,4]]}

Теперь решение, которое я предлагаю:

# First build your array of array
$z = (1,2),(3,4)

# Then build a PSCustom object
$a = [pscustomobject]@{"series" = ,@{"metric"="custom.powershell.gauge"; "points"=$z}}

# At the end convert it to JSON
# don't forget the **Depth** parameter (use **Compress** to retreive one line like above)
$a | ConvertTo-Json -Depth 5

Для меня это дает что-то близкое к тому, что вам нужно:

{
    "series":  [
                   {
                       "points":  [
                                      [
                                          1,
                                          2
                                      ],
                                      [
                                          3,
                                          4
                                      ]
                                  ],
                       "metric":  "custom.powershell.gauge"
                   }
               ]
}

Поздно к вечеринке, но я хотел бы предложить более визуально интуитивно понятное решение, которое легко разворачивать (я, как и другие, я визуальный ученик, поэтому блоки кода, подобные приведенным ниже, помогают мне легче понимать вещи):

[int][double]$unixtime = Get-Date ((Get-Date).ToUniversalTime()) -UFormat %s
$value = Get-Random -Minimum 0 -Maximum 100
$body = @{
    'series' = @(
        [Ordered]@{
            'metric'='custom.powershell.gauge'
            'points' = @(
                ,@($unixtime,$value)
            )
        }
    )  
}
ConvertTo-Json -InputObject $body -Depth 4

Выходы:

{
    "series":  [
                   {
                       "metric":  "custom.powershell.gauge",
                       "points":  [
                                      [
                                          1473698742,
                                          96
                                      ]
                                  ]
                   }
               ]
}

-Depth 4 получает дополнительный набор квадратных скобок вокруг значений ваших точек, и [Ordered] гарантирует, что хеш-таблица упорядочена так, как было указано. Не забывай -Compress перед отправкой, как сказали другие.

Как предложил JPBlanc, создание пользовательского объекта работало. Ниже мой код:

[long]$value=Get-Random -Minimum 0 -Maximum 100
$points=,@($unixtime, $value)
$metricname="custom.powershell.gauge"

$obj = [pscustomobject]@{"series" = ,@{"metric" = $metricname; "points"=$points}}

$json=$obj | ConvertTo-Json -Depth 5 -Compress

Какие выводы:

{"series":[{"points":[[1434810163,53]],"metric":"custom.powershell.gauge"}]}

Не забудьте указать глубину>2.

Спасибо!

Другие вопросы по тегам