PowerShell优化问询:按名称分组筛选各主版本最高次版本号
优化PowerShell版本筛选代码
问题描述
从REST API获取一批对象,每个对象包含version属性(含major、minor、patch字段)。需要按name字段分组,每组内每个major版本仅保留minor.patch数值最高的对象。现有代码可正常运行,寻求更简洁的PowerShell实现方式。
原始示例数据
id: some-guid name: vsbuild version: {[major, 0], [minor, 209], [patch, 0]} id: some-guid name: vsbuild version: {[major, 0], [minor, 200], [patch, 0]} id: some-guid name: vsbuild version: {[major, 1], [minor, 214], [patch, 0]} id: some-guid name: vsbuild version: {[major, 1], [minor, 200], [patch, 0]} ...
期望输出
id: some-guid name: vsbuild versions: @( {[major, 0], [minor, 209], [patch, 0]}, {[major, 1], [minor, 214], [patch, 0]} ) ... id: some-other-guid name: vstest versions: @( {[major, 0], [minor, 209], [patch, 0]}, {[major, 1], [minor, 214], [patch, 0]} )
当前实现代码
# 筛选指定名称的任务 $tasks = $taskMetadata | Where-Object { $_.name -eq $taskName } # 获取该任务的所有唯一主版本号 $majorversions = $tasks | ForEach-Object { $_.version.major } | Select-Object -Unique # 找出每个主版本对应的最新版本对象 $result = $majorversions | ForEach-Object { $majorversion = $_ $tasks | Where-Object { $_.version.major -eq $majorversion} | Sort-Object { [version]"$($_.version.major).$($_.version.minor).$($_.version.patch)" } | Select-Object -Last 1 } return $result
加载JSON数据的代码
$org = "jessehouwing-brazil" $pat = $env:AZURE_DEVOPS_PAT $url = "https://dev.azure.com/$org" $header = @{authorization = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(".:$pat")))"} $tasks = Invoke-RestMethod -Uri "$url/_apis/distributedtask/tasks?allversions=true" -Method Get -ContentType "application/json" -Headers $header | ConvertFrom-Json $taskMetadata = $tasks.value
优化方案
利用Group-Object直接按name和major版本分组,减少循环次数,代码更简洁高效:
方案1:按名称+主版本分组后取最新
$optimizedResult = $taskMetadata | # 先按name和version.major分组 Group-Object name, @{Name='Major'; Expression={$_.version.major}} | ForEach-Object { # 每组内按版本号降序排序,取第一个(即最新版本) $_.Group | Sort-Object { [version]"$($_.version.major).$($_.version.minor).$($_.version.patch)" } -Descending | Select-Object -First 1 }
方案2:按名称分组后再按主版本处理(匹配期望输出结构)
如果需要生成类似期望的versions集合结构,可以调整为:
$groupedByTask = $taskMetadata | Group-Object name | ForEach-Object { $latestPerMajor = $_.Group | Group-Object { $_.version.major } | ForEach-Object { $_.Group | Sort-Object { [version]"$($_.version.major).$($_.version.minor).$($_.version.patch)" } -Descending | Select-Object -First 1 } # 构造目标输出对象 [PSCustomObject]@{ id = $latestPerMajor[0].id name = $_.Name versions = $latestPerMajor.version } }
这两种方案都省去了单独查询唯一主版本号的步骤,通过一次分组完成核心逻辑,代码更紧凑,执行效率也更高。
内容的提问来源于stack exchange,提问作者jessehouwing
相关产品推荐
相关产品推荐

