【问题标题】:Powershell - How to retrieve Object[] dataPowershell - 如何检索对象 [] 数据
【发布时间】:2021-08-11 22:18:45
【问题描述】:

我正在尝试从 api 请求中获取一些数据,但 rank 它已损坏。 我在一个文件中有这段代码:

$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

当我打印变量 $queryResult$queryResult 时,我不明白为什么 rank 会从 4690 变为 1 .leaderboard 内容清楚地显示 rank=4690,但是当我访问最里面的元素时,它会打印 rank: 1.

为什么排名从 4690 变为 1?

你可以复制代码自己试试,API是公开的。

谢谢

【问题讨论】:

  • 您的 invoke-rest 方法返回一个 PSObject 数组。 $queryResult.leaderboard[0].ranks 会给你正确的值。
  • 请分享你的 json 源代码。远景:Rank 属性是一个包含单个项目 "Rank"=[4690] 的数组。这意味着您可能需要这样做:$queryResult.leaderboard[0].rank.
  • @iRon 是对的;阅读Array.Rank Property

标签: arrays powershell powershell-5.0 powershell-5.1 member-enumeration


【解决方案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 的数组,或者您可以推断它从用于显示的表示:outer {@{profile_id=518981; ..}} 中的{...} 表示该值是一个集合(虽然不一定是一个数组)。

这种显式元素访问 ([0]) 对于您的 其他 属性来说不是必要的原因是因为一个名为 member enumeration 的功能强>:

  • 它允许您方便地使用 collection 上的属性访问,以便返回其 元素 的属性值:

    • 对于 multi 元素集合,元素的属性值以 array ([object[]]) 的形式返回,但是 - 就像在管道中一样 - 带有 single-element 集合,唯一元素的属性值按原样返回。

    • 因此,例如,给定一个对象$obj = [pscustomobject] @{ profile_id = 518981 }

      • 单元素 情况:@($obj).profile_id 实际上与:
        @($obj)[0].profile_id / $obj.profile_id 相同
      • 多元素 情况:@($obj, $obj).profile_id 实际上与:
        $obj | ForEach-Object { $_.profile_id } 相同
  • 但是,如果集合本身具有给定名称的属性,则集合级别的属性优先 - 这就是发生的情况.Rank

    • GitHub issue #7445 讨论了这种情境模糊性并建议引入一个专用运算符,例如%.,以便您可以明确地请求或者常规属性访问或 成员枚举。

    • 作为比使用ForEach-ObjectSelect-Object 更快的一般解决方法,您可以使用.ForEach('rank'),如this answer 中所述。

【讨论】:

    猜你喜欢
    • 2023-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多