JQ: 将对象数组转化为对象,并添加到数组中

9

我有一个更复杂的JQ表达式,用于处理对象数组。

输入内容如下:

[
    { "key": "1", "value": "value 1"},
    { "key": "2", "value": "value 2"},
    { "key": "1", "value": "value 3"},
]

我想要的是这个:

{
    "1": { "values": ["value 1", "value 3"] },
    "2": { "values": ["value 2"] }
}

或者,针对我的使用情况:
{
    "1": [ "value 1", "value 3" ],
    "2": [ "value 2" ]
}

也可以。

我已经尝试使用… | { (.key): [.value] },但结果是(对我来说并不奇怪),后面出现的键只是简单地覆盖已经存在的键。我的目标是“创建一个新的键/值对或将.value添加到已经存在的‘values’数组中”。

2个回答

5
使用group_by的解决方案的缺点在于,group_by需要进行排序,这在此处是不必要的。在本响应中,我将展示如何通过使用一种通用(且通常非常有用)的jq函数来避免任何排序,该函数“融合”JSON对象数组,基本上是通过将每个键的值弹出到一个数组中,然后连接相应的数组。
# input should be an array of objects
def meld:
  reduce .[] as $o
    ({}; reduce ($o|keys)[] as $key (.; .[$key] += [$o[$key]] ));

让我们也定义一些数据:

def data:
[
    { "key": "1", "value": "value 1"},
    { "key": "2", "value": "value 2"},
    { "key": "1", "value": "value 3"}
]
;

然后是过滤器:
data |  map([.] | from_entries) | meld

生成:

{"1":["value 1","value 3"],"2":["value 2"]}

2

好的,终于找到了我想要的内容,我也理解了我的先前过滤器没有保留输入数组,而是在彼此之后输出对象的原因。这基本上就是为什么我找到的所有示例都不起作用的原因。

我想按键分组(因此需要键/值要求),这正是group_by所做的,但不起作用。

从分组工作到我的解决方案(唯一键,数组中的值)只有一小步。

'… group_by(.key) | map({ "key": .[0].key, "values": map(.value) | unique })'

现在的输出看起来像这样,对我的需求来说完全可以接受:
[
    {
        "key": "1",
        "values": [
            "value 1",
            "value 3"
        ],
    },
    {
        "key": "2",
        "values": [
            "value 2"
        ]
    }
]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接