使用jq在特定键上组合两个对象数组

时间:2019-03-02 08:11:30

标签: jq

我正在尝试使用jq解决此问题。

假设我有以下对象

{
  "listA": [
    {
      "id": "12345",
      "code": "001"
    }
  ]
  "listB": [
    {
      "id": "12345",
      "prop": "AABBCC"
    }
  ]
}

实际上,我的两个列表较长,但是在每个列表中都没有重复id

我如何将两个列表合并到一个列表中,其中每个项目都是一个对象,并且给定id的非id属性被收集到一个对象中?

例如,从上面的对象中,我想要以下内容:

{
  "listC" : [
    {
      "id": "12345",
      "code": "001",
      "prop": "AABBCC"
    }
  ]
}

2 个答案:

答案 0 :(得分:1)

使用group_by需要进行排序,这是不必要的,因此,如果要考虑效率,则应考虑以下替代方法:

INDEX(.listA[]; .id) as $one
| INDEX(.listB[]; .id) as $two
| reduce ($one|keys_unsorted[]) as $k ($two; .[$k] += $one[$k])
| {listC: [.[]] }

答案 1 :(得分:-1)

一种简单的方法是连接数组,按id将元素分组,并使用add将每个组映射到单个对象中。

jq '.listA+.listB | group_by(.id) | map(add)' test.json

如果您需要在文件中合并两个以上的数组,则可以改用flatten来连接所有数组。

下面的测试用例

# cat test.json

{
  "listA": [
    { "id": "12345", "code": "001" },
    { "id": "12346", "code": "002" }
  ],
  "listB": [
    { "id": "12345", "prop": "AABBCC" }
  ]
}

# jq 'flatten | group_by(.id) | map(add)' test.json
# or
# jq '.listA+.listB | group_by(.id) | map(add)' test.json

[
  {
    "id": "12345",
    "code": "001",
    "prop": "AABBCC"
  },
  {
    "id": "12346",
    "code": "002"
  }
]