英文:
jq: parse result where some properties are empty arrays
问题
使用 jq,希望解析可能包含数组值的结果
混淆了。如果数据包含一个空数组:
"connections": []
认为可以使用 jq 来解析它:
connections: .connections[]? | { id: .id }
例如,"apps"
是一个数组,每个 app
由以下定义:
"actions"
数组"connections"
数组
这里的结果是,apps
包含一个将 connections
设置为空数组的 app
实例。
"apps": [
{
"id": "1a902fb4-1b43-4df9-b9d7-9b54cd14e2ad",
"actions": [
{
"id": "0dc38f41-49fe-4056-b035-850764733a44",
}
],
"connections": []
},
]
假设所有 apps
目前都包含空数组的 connections
。
使用 jq,解析 apps
但不包括空的 connections
(所有目前都包含空数组),没有问题,结果被解析:
apps: .apps[]? | { id: .id \
, actions: .actions[]? | { id: .id }
}
使用 jq,解析 apps
包括空的 connections
,没有结果,什么都没有:
instances: .instances[]? | { id: .id \
, actions: .actions[]? | { id: .id } \
, connections: .connections[]? | { id: .id } \
}
我漏掉了什么?
英文:
Using jq, wish to parse results that may include array values
Confused. If data contains an empty array:
"connections": []
Thought that jq would be able to parse it with:
connections: .connections[]? | { id: .id }
For example, "apps"
is an array, and each app
is defined with the following:
"actions"
array"connections"
array
Here result where apps
has an app
instance that contains connections
as an empty array.
"apps": [
{
"id": "1a902fb4-1b43-4df9-b9d7-9b54cd14e2ad",
"actions": [
{
"id": "0dc38f41-49fe-4056-b035-850764733a44",
}
],
"connections": []
},
]
Assume all apps
have connections
currently containing empty arrays.
Using jq, parsing apps
without including connections
(all currently contain empty arrays), no problem, result is parsed:
apps: .apps[]? | { id: .id \
, actions: .actions[]? | { id: .id }
}
Using jq, parsing apps
including empty connections
, no results, nothing:
instances: .instances[]? | { id: .id \
, actions: .actions[]? | { id: .id } \
, connections: .connections[]? | { id: .id } \
}
What am I missing?
答案1
得分: 1
.connections[]
将流式传输connection
的元素。在对象构造过滤器内使用时,这将为流中的每个元素创建一个对象。
如果涉及多个流,将构建笛卡尔积。
如果数组为空,将不会进行流式传输(因此,产品将为空;请参见底部的示例)。
这是一个示例:
$ jq -cn '{
a: [1, 2],
b: [3, 4]
}
| { x: (.a[] | . + 10), y: (.b[] | . + 20) }'
{"x":11,"y":23}
{"x":11,"y":24}
{"x":12,"y":23}
{"x":12,"y":24}
请注意,?
仅对缺少的值/属性产生影响。空数组不是缺失,它有一个值:空数组本身。
您可能希望使用map
过滤器,例如从您的连接中提取id数组:{ connections: (.connections | map({id})) }
。
使用map
重写上面的示例:
$ jq -cn '{
a: [1, 2],
b: [3, 4]
}
| { x: .a | map(. + 10), y: .b | map(. + 20) }'
{"x":[11,12],"y":[23,24]}
空的笛卡尔积:
$ jq -cn '{
a: [1, 2],
b: [3, 4],
c: []
}
| { x: (.a[] | . + 10), y: (.b[] | . + 20), z: (.c[] | . + 30) }'
$ # 空
$ jq -cn '{
a: [1, 2],
b: [3, 4],
c: []
}
| { x: .a | map(. + 10), y: .b | map(. + 20), z: .c | map(. + 30) }'
{"x":[11,12],"y":[23,24],"z":[]}
英文:
.connections[]
will stream the elements of connection
. When using inside an object construction filter, this will create one object per element in the stream.
If there are multiple streams involved, the cartesian product will be built.
If the array is empty, nothing will be streamed (and consequently, the product will be empty; see example at the bottom).
Here's an example:
$ jq -cn '{
a: [ 1, 2 ],
b: [ 3, 4 ]
}
| { x: (.a[] | . + 10), y: (.b[] | . + 20) }'
{"x":11,"y":23}
{"x":11,"y":24}
{"x":12,"y":23}
{"x":12,"y":24}
Note that ?
only has an effect on missing values/properties. An empty array is not missing, it has a value: the empty array itself.
You probably want to use the map
filter, e.g. to extract an array of ids from your connections: { connections: (.connections | map({id})) }
.
Rewriting the example from above with map
:
$ jq -cn '{
a: [ 1, 2 ],
b: [ 3, 4 ]
}
| { x: .a | map(. + 10), y: .b | map(. + 20) }'
{"x":[11,12],"y":[23,24]}
Empty cartesian product:
$ jq -cn '{
a: [ 1, 2 ],
b: [ 3, 4 ],
c: []
}
| { x: (.a[] | . + 10), y: (.b[] | . + 20), z: (.c[] | . + 30) }'
$ # empty
$ jq -cn '{
a: [ 1, 2 ],
b: [ 3, 4 ],
c: []
}
| { x: .a | map(. + 10), y: .b | map(. + 20), z: .c | map(. + 30) }'
{"x":[11,12],"y":[23,24],"z":[]}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论