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

时间:2016-03-17 16:53:50

标签: json jq

我在使用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"
  }
]

任何建议都将不胜感激!

3 个答案:

答案 0 :(得分:1)

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

您可以使用此过滤器:

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

这是一个类似于peak addvalues 解决方案的版本,为了清晰起见,缩进并注释了一下。它使用+ =来组合数组

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