JQ объединить JSON массивы без дубликатов - PullRequest
0 голосов
/ 12 июня 2018

Я изо всех сил пытаюсь объединить два массива JSON с jq, потому что я хотел бы удалить дублирующиеся ключи в объединенных объектах:

Редактировать : добавлен второй ключ, так как пример был слишком прост.

file1.json:

[
  {"a": 1, "value": 11},
  {"b": 2},
  {"c": 3}
]

file2.json:

[
  {"a": 4, "value": 44},
  {"b": 5},
  {"d": 6}
]

Ожидаемый результат:

[
  {"a": 4, "value": 44},
  {"b": 5},
  {"c": 3},
  {"d": 6}
]

jq add file1.json file2.json дублируетключи (у меня есть два объекта с ключом «а» в массиве).

Я пробовал много ответов из Интернета, но у каждого есть свой вариант использования, и ни один не работал напрямую.Наиболее близким является этот: JQ - объединение двух массивов , но мне не удается заставить его работать с файлами вместо строковых аргументов.

Моя последняя попытка была

jq \
  --slurpfile base file1.json \
  --slurpfile params file2.json \
  '$base + $params | unique_by(.Key)'

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

[Этот ответ был отредактирован с учетом изменения Q.]

В следующем решении используется INDEX/2, как определено в https://github.com/stedolan/jq/blob/master/src/builtin.jq Одно из преимуществ использования INDEX заключается в том, что оноизбегает использования group_by, что влечет за собой затраты на сортировку, что может быть нежелательно в любом случае.

Если ваша версия jq не имеет INDEX/2, вот ее определение:

def INDEX(stream; idx_expr):
  reduce stream as $row ({};
    .[$row|idx_expr|
      if type != "string" then tojson
      else .
      end] |= $row);

Этот фильтр (INDEX/2) создает словарь, ключи которого равны различным значениям idx_expr, примененным к элементам потока, так что значение, связанное с конкретным ключом, является last элемент в потоке, сопоставляемый с этим значением.

[INDEX( add[] | to_entries; (.[0] | .key) )[]
 | from_entries ]

Вызов:

jq -scf program.jq file1.json file2.json

Вывод:

[{"a":4,"value":44},{"b":5},{"c":3},{"d":6}]
0 голосов
/ 12 июня 2018

jq решение:

jq --slurpfile file2 file2.json \
'. + $file2[] | map(to_entries) | flatten 
 | group_by(.key) | map(.[-1] | {(.key): .value})' file1.json

Выход:

[
  {
    "a": 4
  },
  {
    "b": 5
  },
  {
    "c": 3
  },
  {
    "d": 6
  }
]
...