You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在任意结构JSON中递归统计指定值的出现次数?

递归统计任意JSON结构中指定值的出现次数

现有实现

我已经找到一种统计任意结构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

更简洁的实现方案

方案1:.. + reduce(最简洁高效)

直接遍历所有递归节点,用reduce累加符合条件的次数,无需构造中间数组:

{
cat <<EOF
{
    "a": 3,
    "b": 4,
    "c": 3,
    "d": {
        "e": 3
    },
    "f": 6
}
EOF
} | jq 'reduce .. as $item (0; if $item == 3 then . + 1 else . end)'

方案2:简化数组筛选方式

原方法可以去掉对object的冗余判断,因为..会自动展开所有嵌套节点(包括object的每个值),直接筛选目标值即可:

{
cat <<EOF
{
    "a": 3,
    "b": 4,
    "c": 3,
    "d": {
        "e": 3
    },
    "f": 6
}
EOF
} | jq '[.. | select(. == 3)] | length'

方案3:正确使用walk函数

利用walk递归遍历节点,收集所有符合条件的值后统计数量:

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

内容的提问来源于stack exchange,提问作者Zelphir Kaltstahl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 05:22:46