【问题标题】:jq: Objects with array values not combining as expectedjq:具有数组值的对象未按预期组合
【发布时间】:2016-03-17 16:53:50
【问题描述】:

我在使用 jq 组合多个对象时遇到问题。在这种情况下,MY_OBJECTS 是一个 json 对象流,每个对象都有一个键。我将它们组合成一个数组,如下所示:

$ echo ${MY_OBJECTS} | jq -s '.'
[
  {
    "Name1": [
      {
        "Item1": "Val1",
        "Item2": "Val2"
      }
    ]
  },
  {
    "Name1": [
      {
        "Item1": "Val3",
        "Item2": "Val4"
      }
    ]
  },
  {
    "Name2": [
      {
        "Item1": "Val5",
        "Item2": "Val6"
      }
    ]
  },
  {
    "Name2": [
      {
        "Item1": "Val7",
        "Item2": "Val8"
      }
    ]
  }
]

我想将这些组合成一个对象,以便将一个名称下的所有 Item 对象组合成一个数组。本质上,我想产生以下输出:

$ echo ${MY_OBJECTS} | jq -s <SOME_COMMAND>
{
  "Name1": [
    {
      "Item1": "Val1",
      "Item2": "Val2"
    },
    {
      "Item1": "Val3",
      "Item2": "Val4"
    }
  ],
  "Name2": [
    {
      "Item1": "Val5",
      "Item2": "Val6"
    },
    {
      "Item1": "Val7",
      "Item2": "Val8"
    }
  ]
}

我曾期望echo ${MY_OBJECT} | jq -s add 这样做,但是这会用以下对象覆盖每个对象,而不是添加数组,以便它们都在一个数组中(就像添加对象而不是数组一样)。换句话说,这些条目看起来像这样:

"Name1": [
  {
    "Item1": "Val3",
    "Item2": "Val4"
  }
]

虽然我希望它们看起来像这样:

"Name1": [
  {
    "Item1": "Val1",
    "Item2": "Val2"
  },
  {
    "Item1": "Val3",
    "Item2": "Val4"
  }
]

任何建议将不胜感激!

【问题讨论】:

    标签: json jq


    【解决方案1】:

    您需要按对象的键对对象进行分组。如果将对象映射为条目,则可以访问键。然后与组一起构建结果对象。

    你可以使用这个过滤器:

    map(to_entries | add)
        | group_by(.key)
        | map({ (.[0].key): map(.value) | add })
    

    【讨论】:

      【解决方案2】:

      group_by/1 的实现需要排序,所以这里有一个替代方法,它使用了一个通用的过滤器 addvalues,它不需要任何排序。请注意,对输入数组中对象的唯一要求是每个键的值必须与add 兼容。

      # Given an array of objects, combine keys using add/0.
      # This implementation does not depend on sorting.
      def addvalues:
        reduce .[] as $o
          ( {}; reduce ($o|keys[]) as $key
            ( .; . + {($key): (.[$key] + $o[$key])} ));
      
      
      addvalues
      

      【讨论】:

        【解决方案3】:

        这是一个类似于 peakaddvalues 解决方案的版本,为了清楚起见,缩进和注释了一点。它使用 += 来组合数组

        reduce .[] as $i (                 #     $i: {"Name1":[{"Item1":"Val1","Item2":"Val2"}]}
             {}                            #
           ; reduce ($i|keys[]) as $k (    #     $k: "Name1"
                  .                        #
                ; .[$k] += $i[$k]          # $i[$k]: [{"Item1":"Val1","Item2":"Val2"}]
             )
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-10-27
          • 1970-01-01
          • 1970-01-01
          • 2015-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多