jq合并没有重复的json数组

时间:2018-06-12 13:16:42

标签: arrays json jq

我正在努力将两个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复制键(我有两个对象,数组中的键为“a”。)

我在网上尝试了很多答案,但每个人都有自己的用例,没有一个直接工作。最接近的是这个:JQ - Merge two arrays 但我无法设法使用文件而不是字符串参数。

我的最后一次尝试是

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

[此答案已经过编辑,以反映Q中的变化。]

以下解决方案使用https://github.com/stedolan/jq/blob/master/src/builtin.jq中定义的INDEX/2 使用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}]