jq 计算值的出现次数

问题描述 投票:0回答:1

我发现了以下方法来计算任意结构化 JSON 中的值:

{
cat <<EOF
{
    "a": 3,
    "b": 4,
    "c": 3,
    "d": {
        "e": 3
    },
    "f": 6
}
EOF
} | jq '[..
        | if type == "object"
          then select(.value)
          else .
          end
        ] | map(select(. == 3)) | length'

在任意结构的 JSON 中是否有更短的递归计数方法?

我在想是不是需要用

walk
,但是只能找到下面的,不知道最后怎么算:

{
cat <<EOF
{
    "a": 3,
    "b": 4,
    "c": 3,
    "d": {
        "e": 3
    },
    "f": 6
}
EOF
} | jq '..
        | walk(if type == "object"
               then to_entries
                    | map(select(.value))
                    | from_entries
               else .
               end
        )
        | (. == 3)'

产量:

false
true
false
true
false
true
false
jq counting
1个回答
0
投票

您可以梳理流表示,过滤出匹配项,并即时计数:

jq 'reduce tostream[1] as $v (0; if $v == 3 then .+1 else . end)'

同样,您可以使用

..
递归迭代,并仅考虑
scalars
(或
numbers
):

jq 'reduce (.. | scalars) as $v (0; if $v == 3 then .+1 else . end)'

或者将条件移动到迭代生成器中,这样你就可以在主体中无条件计数:

jq 'reduce (.. | select(numbers == 3)) as $_ (0; .+1)'
© www.soinside.com 2019 - 2024. All rights reserved.