JQ:将对象数组简化为对象,然后添加到数组

Ale*_*lex 5 arrays json addition jq

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

输入看起来像这样:

[
    { "key": "1", "value": "value 1"},
    { "key": "2", "value": "value 2"},
    { "key": "1", "value": "value 3"},
]
Run Code Online (Sandbox Code Playgroud)

我想要得到的是:

{
    "1": { "values": ["value 1", "value 3"] },
    "2": { "values": ["value 2"] }
}
Run Code Online (Sandbox Code Playgroud)

或者,对于我的用例:

{
    "1": [ "value 1", "value 3" ],
    "2": [ "value 2" ]
}
Run Code Online (Sandbox Code Playgroud)

也可以。

我已经尝试过使用它,… | { (.key): [.value] }但是结果是(以后没有出现任何意外),以后出现的键只会覆盖已经存在的键。我要完成的工作类似于“创建新的键/值对或将.value添加到已经存在的'values'数组中”。

pea*_*eak 5

依赖解决方案的缺点group_bygroup_by需要排序,这在这里是不必要的。在此响应中,我将展示如何通过使用通用(且通常有用)的 jq 函数来避免任何排序,该函数“融合”JSON 对象数组,本质上是将每个键的值弹出到数组中,然后连接相应的值数组。

# input should be an array of objects
def meld:
  reduce .[] as $o
    ({}; reduce ($o|keys)[] as $key (.; .[$key] += [$o[$key]] ));
Run Code Online (Sandbox Code Playgroud)

我们还定义一些数据:

def data:
[
    { "key": "1", "value": "value 1"},
    { "key": "2", "value": "value 2"},
    { "key": "1", "value": "value 3"}
]
;
Run Code Online (Sandbox Code Playgroud)

然后是过滤器:

data |  map([.] | from_entries) | meld
Run Code Online (Sandbox Code Playgroud)

产生:

{"1":["value 1","value 3"],"2":["value 2"]}
Run Code Online (Sandbox Code Playgroud)