如何使用JQ与相同的密钥合并/JOIN/CONCAT值



我需要按键汇总值。示例JSON输入是:

$ cat json | jq 
[
  {
    "key": "john",
    "value": "ontario"
  },
  {
    "key": "ryan",
    "value": "chicago"
  },
  {
    "key": "ryan",
    "value": "illinois"
  },
  {
    "key": "john",
    "value": "toronto"
  },
]

是可能的,如果是这样,如何与相同的密钥合并/join/Concat值,以便结果为:

[
  {
    "key": "john",
    "value": "toronto ontario"
  },
  {
    "key": "ryan",
    "value": "illinois chicago"
  },
]

我特别是因为它易于使用Cfengine。

按键组对成对,然后组合值。

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

对于这种类型的问题,我更喜欢避免排序的开销,并确保尊重输入中对象的排序。

这是一种假设与"键"one_answers"值"相关的值的方法是字符串(如示例中的情况(。此假设使避免效率低下的查找变得容易:

def merge_by_key(separator):
  reduce .[] as $o
    ({}; $o["key"] as $k
         | if .[$k] then .[$k] += (separator + $o["value"])
           else .[$k] = $o["value"] end);
merge_by_key(" ") | to_entries

输出:

[{"key":"john","value":"ontario toronto"},
 {"key":"ryan","value":"chicago illinois"}]

通用解决方案

def merge_at_key(separator):
  reduce .[] as $o
    ([];
     $o["key"] as $k
     | (map(.key) | index($k)) as $i
     | if $i then (.[$i] | .value) += (separator + $o["value"])
       else . + [$o] end);

最新更新