JQ:将对象数组减少为对象,添加到数组
JQ: Reduce array of objects to object, adding to array
我有一个处理对象数组的更复杂的 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] }
但结果是(对我来说并不奇怪)后来出现的键只是覆盖了已经存在的键。我想要完成的是 "create a new key/value pair or add .value to an already existing one's 'values' array".
好的,在终于找到我想要的东西后,我也明白我以前的过滤器没有保留输入数组,而是导致对象一个接一个地输出。所以这基本上就是我找到的所有示例都不起作用的原因。
我想按键分组(因此 key/value 要求),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"
]
}
]
依赖group_by
的解决方案的缺点是group_by
需要排序,这在这里是不必要的。在此响应中,我将展示如何通过使用 "melds" 一个 JSON 对象数组的通用(通常有用的)jq 函数来避免任何排序,本质上是通过将每个键的值弹出到数组,然后拼接相应的数组。
# 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"]}
我有一个处理对象数组的更复杂的 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] }
但结果是(对我来说并不奇怪)后来出现的键只是覆盖了已经存在的键。我想要完成的是 "create a new key/value pair or add .value to an already existing one's 'values' array".
好的,在终于找到我想要的东西后,我也明白我以前的过滤器没有保留输入数组,而是导致对象一个接一个地输出。所以这基本上就是我找到的所有示例都不起作用的原因。
我想按键分组(因此 key/value 要求),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"
]
}
]
依赖group_by
的解决方案的缺点是group_by
需要排序,这在这里是不必要的。在此响应中,我将展示如何通过使用 "melds" 一个 JSON 对象数组的通用(通常有用的)jq 函数来避免任何排序,本质上是通过将每个键的值弹出到数组,然后拼接相应的数组。
# 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"]}