如何计算 JQ 中每个对象的键值对的出现次数?
Posted
技术标签:
【中文标题】如何计算 JQ 中每个对象的键值对的出现次数?【英文标题】:How to count occurrences of a key-value pair per individual object in JQ? 【发布时间】:2021-11-24 03:43:30 【问题描述】:我找不到如何计算按“member_id”分组的“title”的出现... json文件为:
[
"member_id": 123,
"loans":[
"date": "123",
"media": [
"title": "foo" ,
"title": "bar"
]
,
"date": "456",
"media": [
"title": "foo"
]
]
,
"member_id": 456,
"loans":[
"date": "789",
"media": [
"title": "foo"
]
]
]
通过这个查询,我获得了“title==foo”用户的贷款条目
jq '.[] | (.member_id) as $m | .loans[].media[] | select(.title=="foo") | id: $m, title: .title' member.json
"id": 123,
"title": "foo"
"id": 123,
"title": "foo"
"id": 456,
"title": "foo"
但我找不到如何按用户(group by)获取标题的计数,以获得如下结果:
"id": 123,
"title": "foo",
"count": 2
"id": 456,
"title": "foo",
"count": 1
我遇到了类似jq: error (at member.json:31): object ("title":"f...) and array ([[123]]) cannot be sorted, as they are not both arrays
或类似的错误...
【问题讨论】:
【参考方案1】:使用 group_by :
jq 'map(
(.member_id) as $m
| .loans[].media[]
| select(.title=="foo")
| id: $m, title: .title
)
|group_by(.id)[]
|.[0] + count: length
' input-file
【讨论】:
非常感谢 Philippe,我错过了.[0] +
【参考方案2】:
-
当主要目标是计数时,如果确定数组的长度是这样做的唯一原因,那么避免构造数组通常会更有效。例如,在本例中,您可以这样写:
def count(s): reduce s as $x (null; .+1);
"foo" as $title | .[] |
id: .member_id,
$title,
count: count(.loans[].media[] | select(.title == $title))
group_by
有它的用途,但很清楚它即使对于分组也是低效的,因为它的实现涉及排序,如果目标是“分组”某些标准,这不是绝对必要的。完全通用的无排序“分组依据”函数实现起来有点棘手,但通常一个简单但非通用的版本就足够了,例如:
# sort-free variant of group_by/1
# f must always evaluate to an integer or always to a string, which
# could be achieved by using `tostring`.
# Output: an array in the former case, or an object in the latter case
def GROUP_BY(f): reduce .[] as $x (null; .[$x|f] += [$x] );
【讨论】:
以上是关于如何计算 JQ 中每个对象的键值对的出现次数?的主要内容,如果未能解决你的问题,请参考以下文章
java问题,我想在java中存储键值对,以便使用,但是键值对的键和值都有重复元素,使用hashmap会产生覆盖。
如何在 Swift 中实现一个管理 UserDefaults 的键值对的通用结构?