Powershell — как получить данные Object[]

Я пытаюсь получить некоторые данные из запроса API, но ранг повреждается. У меня есть этот код в файле:

$queryResult=Invoke-restmethod -Uri "https://aoe2.net/api/leaderboard?game=aoe2de&leaderboard_id=3&steam_id=76561198011209758"

Write-Output "COMPLETE RETURN"
$queryResult

Write-Output "LEADERBOARD"
$queryResult.leaderboard

Write-Output "INDIVIDUAL ITEMS"
Write-Output $("profile_id: "+$queryResult.leaderboard.profile_id)
Write-Output $("rank: "+$queryResult.leaderboard.rank)
Write-Output $("rating: "+$queryResult.leaderboard.rating)
Write-Output $("steam_id: "+$queryResult.leaderboard.steam_id)
Write-Output $("icon: "+$queryResult.leaderboard.icon)
Write-Output $("name: "+$queryResult.leaderboard.name)
Write-Output $("clan: "+$queryResult.leaderboard.clan)
Write-Output $("country: "+$queryResult.leaderboard.country)
Write-Output $("previous_rating: "+$queryResult.leaderboard.previous_rating)
Write-Output $("highest_rating: "+$queryResult.leaderboard.highest_rating)
Write-Output $("streak: "+$queryResult.leaderboard.streak)
Write-Output $("lowest_streak: "+$queryResult.leaderboard.lowest_streak)
Write-Output $("highest_streak: "+$queryResult.leaderboard.highest_streak)
Write-Output $("games: "+$queryResult.leaderboard.games)
Write-Output $("wins: "+$queryResult.leaderboard.wins)
Write-Output $("losses: "+$queryResult.leaderboard.losses)
Write-Output $("drops: "+$queryResult.leaderboard.drops)
Write-Output $("last_match: "+$queryResult.leaderboard.last_match)
Write-Output $("last_match_time: "+$queryResult.leaderboard.last_match_time)

Всякий раз, когда я запускал его, он показывает:

COMPLETE RETURN


total          : 50403
leaderboard_id : 3
start          : 1
count          : 1
leaderboard    : {@{profile_id=518981; rank=4690; rating=1414; steam_id=76561198011209758; icon=; name=[LdS]Nestoter; clan=LDS14; country=UY; previous_rating=1398; highest_rating=1432; streak=1; lowest_streak=-10; highest_streak=8;
                 games=141; wins=80; losses=61; drops=1; last_match=1619919442; last_match_time=1619919442}}

LEADERBOARD
profile_id      : 518981
rank            : 4690
rating          : 1414
steam_id        : 76561198011209758
icon            :
name            : [LdS]Nestoter
clan            : LDS14
country         : UY
previous_rating : 1398
highest_rating  : 1432
streak          : 1
lowest_streak   : -10
highest_streak  : 8
games           : 141
wins            : 80
losses          : 61
drops           : 1
last_match      : 1619919442
last_match_time : 1619919442

INDIVIDUAL ITEMS
profile_id: 518981
rank: 1
rating: 1414
steam_id: 76561198011209758
icon:
name: [LdS]Nestoter
clan: LDS14
country: UY
previous_rating: 1398
highest_rating: 1432
streak: 1
lowest_streak: -10
highest_streak: 8
games: 141
wins: 80
losses: 61
drops: 1
last_match: 1619919442
last_match_time: 1619919442

Я не понимаю, почему rank меняется с 4690 на 1, когда я печатаю переменную $queryResult и $queryResult.leaderboard< /strong> ясно показывает, что rank=4690, но когда я обращаюсь к самому внутреннему элементу, он печатает rank: 1.

Почему ранг меняется с 4690 на 1?

Вы можете скопировать код и попробовать сами, API общедоступный.

Спасибо


person Nestoter    schedule 23.05.2021    source источник
comment
Ваш метод invoke-rest возвращает массив объектов PSObject. $queryResult.leaderboard[0].ranks даст вам правильное значение.   -  person David Brabant    schedule 23.05.2021
comment
Пожалуйста, поделитесь исходником json. Общий план: свойство Rank представляет собой массив с одним элементом "Rank"=[4690]. Это означает, что вам, вероятно, нужно сделать это: $queryResult.leaderboard[0].rank.   -  person iRon    schedule 23.05.2021
comment
@iRon прав; прочитать свойство Array.Rank.   -  person JosefZ    schedule 23.05.2021


Ответы (1)


iRon предоставил важный указатель: Потому что $queryResult.leaderboard — это массив, который сама имеет свойство .Rank , вы должны явно получить доступ к интересующим элементам, чтобы получить их .rank значение свойства (обратите внимание, что доступ к свойству нечувствителен к регистру в PowerShell, поскольку PowerShell вообще такое):

# Note the [0] for access to the 1st element.
$queryResult.leaderboard[0].rank # -> 4690

Вы можете определить, что $queryResult.leaderboard — это массив с $queryResult.leaderboard | Get-Member или $queryResult.leaderboard.GetType().Name, или вы можете вывести его из представления для отображения: внешний {...} в {@{profile_id=518981; ..}} указывает, что значение представляет собой коллекцию (но не обязательно массив).

Причина, по которой этот явный доступ к элементу ([0]) не необходим для ваших других свойств, связана с функцией, называемой перечисление участников:

  • Он удобно позволяет вам использовать доступ к свойствам в коллекции, чтобы возвращать значения свойств ее элементов:

    • В многоэлементной коллекции значения свойств элементов возвращаются в виде массива ([object[]]), но, как и в конвейере, в случае одноэлементной коллекция, единственное значение свойства элемента возвращается как есть.

    • Поэтому, например, для объекта $obj = [pscustomobject] @{ profile_id = 518981 }:

      • Single-element case: @($obj).profile_id is effectively the same as:
        @($obj)[0].profile_id / $obj.profile_id
      • Случай многоэлементный: @($obj, $obj).profile_id фактически совпадает с:
        $obj | ForEach-Object { $_.profile_id }
  • Однако, если коллекция сама имеет свойство с заданным именем, это свойство уровня коллекции имеет приоритет, что и произошло с .Rank.

    • GitHub issue #7445 обсуждает эту ситуационную двусмысленность и предлагает ввести выделенного оператора< /em>, произнесите %., чтобы можно было однозначно запросить либо обычный доступ к свойствам, или перечисление членов.

    • В качестве общего обходного пути, более быстрого, чем использование ForEach-Object или Select-Object вы можете использовать .ForEach('rank'), как описано в этом ответе.

person mklement0    schedule 23.05.2021