简体   繁体   English

jq:数组值未按预期组合的对象

[英]jq: Objects with array values not combining as expected

I am having trouble using jq to combine multiple objects. 我在使用jq组合多个对象时遇到麻烦。 In this case, MY_OBJECTS is a stream of json objects with a single key each. 在这种情况下,MY_OBJECTS是一个json对象流,每个对象都有一个键。 I combine them into a single array as follows: 我将它们组合成一个数组,如下所示:

$ 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"
      }
    ]
  }
]

I would like to combine these into one object so that all the Item objects under one name are combined into one array. 我想将它们组合成一个对象,以便将一个名称下的所有Item对象组合成一个数组。 Essentially, I would like to produce the following output: 本质上,我想产生以下输出:

$ 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"
    }
  ]
}

I had expected echo ${MY_OBJECT} | jq -s add 我曾期望echo ${MY_OBJECT} | jq -s add echo ${MY_OBJECT} | jq -s add to do this, but this overwrote each object with the following one instead of adding the arrays so that they were all in one array (as though the objects were being added instead of the arrays). echo ${MY_OBJECT} | jq -s add可以做到这一点,但这会用以下对象覆盖每个对象,而不是添加数组,从而使它们全部位于一个数组中(就像要添加对象而不是添加数组一样)。 In other words, the entries looked like this: 换句话说,条目看起来像这样:

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

While I wanted them to look like this: 虽然我希望他们看起来像这样:

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

Any advice would be appreciated! 任何意见,将不胜感激!

You need to group the objects by their keys. 您需要按对象的键对它们进行分组。 You can access the keys if you map the objects as entries. 如果将对象映射为条目,则可以访问键。 Then with the group, build out the result objects. 然后与该组一起构建结果对象。

You can use this filter: 您可以使用以下过滤器:

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

The implementation of group_by/1 requires a sort, so here is an alternative approach that uses a generically useful filter, addvalues , that does not require any sorting. group_by/1的实现需要排序,因此这是使用通用过滤器addvalues的另一种方法,不需要任何排序。 Notice that the only requirement placed on the objects in the input array is that at each key, the values must be compatible with respect to add . 注意,对输入数组中的对象的唯一要求是在每个键处,值必须与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

Here is a version similar to peak 's addvalues solution indented and commented a bit for clarity. 这是一个类似于peakaddvalues解决方案的版本,为了清楚起见,它进行了缩进和注释。 It uses += to combine the arrays 它使用+ =组合数组

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"}]
     )
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM