jq:按值习惯性地聚合对象键

  • 本文关键字:对象 习惯性 jq json jq
  • 更新时间 :
  • 英文 :


假设我有一个JSON对象如下:

{
"Person A": "Accounting",
"Person B": "Accounting",
"Person C": "Production",
"Person D": "Production",
"Person E": "Marketing"
}

我想把它翻过来,这样对于每个部门,我都有一个人员列表,像这样:

{
"Accounting": [
"Person A",
"Person B"
],
"Production": [
"Person C",
"Person D"
],
"Marketing": [
"Person E"
]
}

我对jq还很陌生,并且已经提出了几个功能解决方案,但是每个解决方案都有自己的问题,我希望有一个更好的,更习惯的方法来做到这一点,我只是还没有想到。

jq程序1 (jqplay):

to_entries
| group_by(.value)
| map( { "key": .[0].value, "value": [ .[].key ] } )
| from_entries

这里的低效率在于group_by创建的结构创建了一个需要进一步操作的结构,因此对于结果列表中的每个条目,我们通过获取第一个子条目的值(忽略其他每个子条目的值),然后获取每个子条目的键来构建我们自己的结构。

jq程序2 (jqplay)

to_entries | reduce .[] as $x (
{};
. * {
($x.value): (
(.[$x.value]//[]) + [ $x.key ]
)
}
)

在这里,我们使用reduce来有效地构建我们想要构建的东西,这很好。然而,*不递归+数组,所以我们必须自己处理这部分,这使得一些相当棘手的阅读(至少从我的角度来看)。

你能想到一种更优雅和/或更习惯的方法来在jq中按键聚合对象的值吗?

这里不需要*操作符。像这样的代码应该可以正常工作:

reduce to_entries[] as {$key, $value} ({};
.[$value] += [$key]
)
<<p><一口>在线演示/一口>

最新更新