JQ如何将数组中的多个对象合并为一个(二)

JQ how to merge multiple objects in an array into one (2)

比我的 更复杂一些。缺少索引也会把事情搞砸。

输入:

{
  "a": [
    { "b": 1, "d": "p" },

    { "b": 3, "d": "r" },
    { "b": 4, "d": "s" }
  ],
  "h": [
    { "b": 1, "i": "k" },
    { "b": 2, "i": "l" },

    { "b": 4, "i": "n" }
  ]
}

期望的输出:

{
  "q": [
    { "b": 1, "d": "p", "i": "k" },
    { "b": 2, "i": "l" },
    { "b": 3, "d": "r" },
    { "b": 4, "d": "s", "i": "n" }
  ]
}

尝试过:

jq '[.a, .h ] | transpose | map(add)| {l: .}'
jq '[ .a[] , .h[] ] | unique_by(.b) | { l: sort_by(.b) }'
jq '[ .a[] + .h[] ] | unique_by(.b) | { l: sort_by(.b) }'
jq '[ .a[] * .h[] ] | unique_by(.b) | { l: sort_by(.b) }'

使用 group_by 通过过滤器的输出对数组元素进行分组(在本例中为 .b):

jq '{ q : [ add | group_by(.b)[] | add ] }' file

这里有一个使用通用函数 aggregate_by 的解决方案,定义如下:

def aggregate_by(s; f; g):
  reduce s as $x  (null; .[$x|f] += [$x|g]);

首先,请注意这个 def:

aggregate_by(.a[], .h[]; .b|tostring; .)[]
| add

生成除元素排序之外的所需数组。如果输出数组中元素的顺序不重要,则可以调整以上内容以提供一个简单的解决方案,该解决方案不涉及 group_by,这需要排序。

为了产生所需的(按 b 排序)输出,我们可以按如下方式调整上面的内容:

{q: [aggregate_by(.a[], .h[]; .b|tostring; .)[]]
    | map(add)
    | sort_by(.b) }