使用 PowerShell 比较后从 JSON 数组中获取特定值?

Get specific value from JSON array after comparison using PowerShell?

一旦从 JSON 数组对象

匹配键,我想获得特定值

输入:

[
    {
        "Id": "19A7A3C4",
        "displayName": "somename",
        "tags": [
            {
                "context": "CONTEXTLESS",
                "key": "apple",
                "value": "10"
            },
            {
                "context": "CONTEXTLESS",
                "key": "orange",
                "value": "20"
            },
            {
                "context": "CONTEXTLESS",
                "key": "grapes",
                "value": "30"
            }
        ]
    },
    {
        "Id": "111111",
        "displayName": "somename",
        "tags": [
            {
                "context": "CONTEXTLESS",
                "key": "cat",
                "value": "10"
            },
            {
                "context": "CONTEXTLESS",
                "key": "cat",
                "value": "20"
            }
        ]
    }
]

我想获取标签的值,其中键与 cat 匹配且值与 10 匹配,我使用以下查询但获取整个对象

$content = Get-Content -Raw -Path "data.json" | ConvertFrom-Json
$content | Where-Object{ $_.tags.key -eq "cat" -and $_.tags.value -eq "10"}

期望输出:10

枚举所有标签,然后使用 ForEach-Object 只获取任何匹配项的 value 属性:

$content.tags | Where-Object { $_.key -eq "cat" -and $_.value -eq "10"} |ForEach-Object -MemberName value

已经展示了解决问题的简洁方法。

类似的方法是使用 intrinsic method .Where{}:

$tagValues = $content.tags.Where{ $_.key -eq "cat" -and $_.value -eq "10" }.value

$content.tags 使用 member enumeration 将所有 tags 属性收集到一个数组中。 .Where{} 过滤类似于Where-Object 的数组元素。最后.value再次使用成员枚举将过滤后的标签值收集到一个数组中

.Where{} 这样的内部方法应该比管道命令更快,因为它们不涉及管道机器的开销。


如果要保留原始查询,则必须处理嵌套属性。

使用grouping operator ()和点符号来提取给定的属性:

$tagValues = ($content | Where-Object{ $_.tags.key -eq "cat" -and $_.tags.value -eq "10"}).tags.value

另一种方法是使用参数 -ExpandProperty(别名 -Expand)的 Select-Object,但对于嵌套属性 (yet),它的工作方式并不直接:

$tagValues = $content | Where-Object{ $_.tags.key -eq "cat" -and $_.tags.value -eq "10"} |
    Select-Object -Expand tags | Select-Object -Expand value

更直接的选择是 ForEach-Object:

$tagValues = $content | Where-Object{ $_.tags.key -eq "cat" -and $_.tags.value -eq "10"} |
    ForEach-Object { $_.tags.value }