Используйте jq, чтобы объединить два массива объектов на определенном ключе - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь использовать jq для решения этой проблемы.

Предположим, у меня есть следующий объект

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

На самом деле мои два списка длиннее, но idне повторяется в каждом списке.

Как я могу объединить два списка в один список, где каждый элемент является объектом со свойствами, отличными от id для данного id, которые собираются в одинобъект?

Например, из вышеприведенного объекта мне бы хотелось следующее:

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

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Использование group_by влечет за собой сортировку, которая не нужна, поэтому, если эффективность является проблемой, то следует рассмотреть альтернативный подход, такой как следующий:

INDEX(.listA[]; .id) as $one
| INDEX(.listB[]; .id) as $two
| reduce ($one|keys_unsorted[]) as $k ($two; .[$k] += $one[$k])
| {listC: [.[]] }
0 голосов
/ 02 марта 2019

Простой способ - объединить массивы, сгруппировать элементы по 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"
  }
]
...