如何用JMESPath扁平化JSON数组并生成投票者统计键值对?
问题描述
我有一个JSON对象,结构如下:
{ "data": { "votes": [ { "id": "0x0d185b44dc6a9e4077d44a29fccc22d1f6238192107d08afa890a1bdddc01e10", "voter": "0x4Aad3544bE38067F534b6B516f9E645D495c4062" }, { "id": "0xf141aa62dc57b20fb6ea1197df44ba0ab4de166c8c19302553065788812beea1", "voter": "0xB01f126C9041CC230e91378d688450Db4c3510cA" }, { "id": "0xf141aa62dc57b20fb6ea1197df44ba0ab4de166c8c19302553065788812beea1", "voter": "0xB01f126C9041CC230e91378d688450Db4c3510cA" } ] } }
需要提取其中的voter值,生成指定格式的字典,优先实现理想结果,若无法实现,两种可接受结果也可以:
可接受结果1
{ "0x4Aad3544bE38067F534b6B516f9E645D495c4062": "1", "0xB01f126C9041CC230e91378d688450Db4c3510cA": "1" }
可接受结果2
{ "0x4Aad3544bE38067F534b6B516f9E645D495c4062": "1", "0xB01f126C9041CC230e91378d688450Db4c3510cA": "1", "0xB01f126C9041CC230e91378d688450Db4c3510cA": "1" }
理想结果
{ "0x4Aad3544bE38067F534b6B516f9E645D495c4062": "1", "0xB01f126C9041CC230e91378d688450Db4c3510cA": "2" }
目前测试的表达式无法得到预期结果,请求实现上述目标。
解决方案
实现理想结果(统计voter出现次数)
使用JQ工具执行以下命令:
jq '.data.votes | group_by(.voter) | map({(.[0].voter): (length|tostring)}) | add' input.json
逻辑说明:
- 提取
data.votes数组 - 按
voter字段分组 - 每个分组生成键为voter值、值为分组长度(转为字符串)的对象
- 合并所有对象为最终字典
实现可接受结果1(去重voter,值统一为"1")
使用JQ工具执行以下命令:
jq '.data.votes | map(.voter) | unique | map({(.): "1"}) | add' input.json
逻辑说明:
- 提取所有voter值组成数组
- 对数组去重
- 将每个voter转为键为自身、值为"1"的对象
- 合并所有对象为最终字典
实现可接受结果2(保留重复voter,注意:JSON标准不允许重复键,实际解析会覆盖,仅作格式展示)
使用JQ工具生成对应格式的字符串:
jq -r '.data.votes | map("\"\(.voter)\": \"1\"") | join(",\n ") | "{\\n \(. )\\n}"' input.json
逻辑说明:
- 将每个voter转为键值对字符串
- 用换行和逗号拼接所有键值对
- 包裹成对象格式的字符串
内容的提问来源于stack exchange,提问作者Sam Polgar
相关产品推荐
相关产品推荐

