В этом очень эффективен следующий подход:
(a) используется тот факт, что file1.json и file2.json являются потоками объектов, что позволяет избежать использования памяти, необходимой для хранения этих объектов в виде массивов;
(b) избегает сортировки (как, например, по group_by
)
Ключевой концепцией является добавление объектов по ключу. Для выполнения сложения по ключу объектов в потоке мы определяем следующую обобщенную функцию:
# s is assumed to be a stream of mutually
# compatible objects in the sense that, given
# any key of any object, the values at that key
# must be compatible w.r.t. `add`
def keywise_add(s):
reduce s as $x ({};
reduce ($x|keys_unsorted)[] as $k (.;
.[$k] += $x[$k]));
Теперь задачу можно выполнить следующим образом:
keywise_add(inputs | {(.inst_id): .tag_id} )
| keys_unsorted[] as $k
| {tag_id: .[$k], inst_id: $k}
Воззвание
С помощью вышеуказанной программы в add.jq вызов:
jq -c -n -f add.jq file1.json file2.json
дает:
{"tag_id":["t1","t2"],"inst_id":"s1"}
{"tag_id":["t1","t2"],"inst_id":"s2"}
{"tag_id":["t2"],"inst_id":"s3"}
Протест
Выше предполагается, что inst_id
является строковым значением. Если это не так, то вышеупомянутый подход все еще можно использовать, если между inst_id|tostring
нет коллизий, что было бы, например, если бы inst_id
всегда было числовым.