【问题标题】:how to use jq to merge/join/concat values with the same key如何使用 jq 合并/加入/连接具有相同键的值
【发布时间】:2017-09-16 02:31:21
【问题描述】:

我需要按键聚合值。示例 JSON 输入是:

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

是否有可能,如果可以,如何使用相同的键合并/加入/连接值,以便结果是:

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

我专门针对 JQ,因为它在 cfengine 中易于使用。

【问题讨论】:

    标签: json join merge concat jq


    【解决方案1】:

    按键分组,然后组合值。

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

    【讨论】:

      【解决方案2】:

      对于这类问题,我更喜欢避免排序的开销,并保证输入中对象的顺序得到尊重。

      这是一种假设与“key”和“value”关联的值都是字符串的方法(如示例中的情况)。这种假设可以很容易地避免低效的查找:

      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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-17
        • 2019-12-20
        • 1970-01-01
        相关资源
        最近更新 更多