通过按键过滤数组,使用 jq 展平 JSON 文档
Posted
技术标签:
【中文标题】通过按键过滤数组,使用 jq 展平 JSON 文档【英文标题】:Flatten a JSON document using jq by filtering an array by keys 【发布时间】:2021-07-02 16:49:48 【问题描述】:我有一个格式如下的 JSON:
"subFields": [
"id": "question_1",
"type": "radioGroup",
"description": "Description1",
"title": "title1",
"subFields": [
"type": "radio",
"label": "Yes",
"value": 1
,
"type": "radio",
"label": "No",
"value": 0
,
"uiComponent": "SmallContent",
"componentProps":
"text": "* If the answer to the above question is “Yes”, please contact the Support immediately."
]
,
"uiComponent": "Spacer"
,
"id": "question_2",
"type": "radioGroup",
"description": "Description2",
"title": "Title2",
"subFields": [
"type": "radio",
"label": "Label - Value 1",
"value": 1
,
"type": "radio",
"label": "Label - Value 2",
"value": 2
,
"type": "radio",
"label": "Label - Value 3",
"value": 3
,
"type": "radio",
"label": "Other",
"value": 13,
"subFields": [
"id": "question_2a",
"type": "string",
"condition":
"type": "BinaryExpression",
"operator": "==",
"left":
"type": "Identifier",
"name": "question_2"
,
"right":
"type": "Literal",
"value": 13
]
]
,
"id": "question_2_b",
"style":
"marginTop": "30px"
,
"type": "radioGroup",
"description": "Description3",
"title": "",
"subFields": [
"type": "radio",
"label": "Label - Radio 1",
"value": 1
,
"type": "radio",
"label": "Label - Radio 2",
"value": 2
,
"type": "radio",
"label": "Label - Radio 3",
"value": 3
]
,
"uiComponent": "Spacer"
,
"id": "question_3",
"type": "radioGroup",
"description": "Description3",
"title": "Title3",
"subFields": [
"type": "radio",
"label": "Yes",
"value": 1
,
"type": "radio",
"label": "No",
"value": 0
]
,
"uiComponent": "Spacer"
,
"condition":
"type": "BinaryExpression",
"operator": "==",
"left":
"type": "Identifier",
"name": "signer_type"
,
"right":
"type": "Literal",
"value": "entity"
,
"subFields": [
"uiComponent": "Spacer"
,
"id": "question_4",
"type": "radioGroup",
"description": "Description_4",
"title": "Title_4",
"subFields": [
"type": "radio",
"label": "Yes",
"value": 1
,
"type": "radio",
"label": "No",
"value": 0
]
,
"uiComponent": "Spacer"
],
"uiComponent": "Block"
,
"uiComponent": "Spacer"
],
"uiComponent": "Container"
我想生成以下输出:
[
"id": "question_1",
"title": "title1",
"description": "Description1",
"type": "radioGroup",
"questions": "radio,Yes,1"
,
"id": "question_1",
"title": "title1",
"description": "Description1",
"type": "radioGroup",
"questions": "radio,No,0"
,
"id": "question_2",
"title": "Title2",
"description": "Description2",
"type": "radioGroup",
"questions": "radio,Label - Value 1,1"
,
"id": "question_2",
"title": "Title2",
"description": "Description2",
"type": "radioGroup",
"questions": "radio,Label - Value 2,2"
,
"id": "question_2",
"title": "Title2",
"description": "Description2",
"type": "radioGroup",
"questions": "radio,Label - Value 3,3"
,
"id": "question_2_b",
"title": "",
"description": "Description3",
"type": "radioGroup",
"questions": "radio,Label - Value 1,1"
,
"id": "question_2_b",
"title": "",
"description": "Description3",
"type": "radioGroup",
"questions": "radio,Label - Value 2,2"
,
"id": "question_2_b",
"title": "",
"description": "Description3",
"type": "radioGroup",
"questions": "radio,Label - Value 3,3"
,
"id": "question_3",
"title": "Title3",
"description": "Description3",
"type": "radioGroup",
"questions": "radio,Yes,1"
,
"id": "question_3",
"title": "Title3",
"description": "Description3",
"type": "radioGroup",
"questions": "radio,No,0"
]
或替代的简化版本:
[
"question_1",
"title1",
"Description1",
"radioGroup",
"radio,Yes,1",
"radio,No,0"
],
[
"question_2",
"title2",
"Description2",
"radioGroup",
"radio,Label - Value 1,1",
"radio,Label - Value 2,2",
"radio,Label - Value 3,3",
],
[
"question_2_b",
"Description3",
"radioGroup",
"radio,Label - Value 1,1",
"radio,Label - Value 2,2",
"radio,Label - Value 3,3",
],
[
"question_3",
"Title3",
"Description3",
"radioGroup",
"radio,Yes,1",
"radio,No,0"
]
目标是仅获取包含 id 的对象(删除 "uiComponent": "Spacer" 对象)并仅获取 subFields 与数组中的这些标签:
"subFields": [
"type": "xxxx",
"label": "xxxx",
"value": xxxx
,
我能够使用以下 JQ 模式展平 JSON 数组:
jq play 1
.subFields[] | select(has("id") and .id != null)| id: .id, type: .type, description: .description, anwers: .subFields
并生成了这个结果:
"id": "question_1",
"type": "radioGroup",
"description": "Description1",
"anwers": [
"type": "radio",
"label": "Yes",
"value": 1
,
"type": "radio",
"label": "No",
"value": 0
,
"uiComponent": "SmallContent",
"componentProps":
"text": "* If the answer to the above question is “Yes”, please contact the Support immediately."
]
"id": "question_2",
"type": "radioGroup",
"description": "Description2",
"anwers": [
"type": "radio",
"label": "Label - Value 1",
"value": 1
,
"type": "radio",
"label": "Label - Value 2",
"value": 2
,
"type": "radio",
"label": "Label - Value 3",
"value": 3
,
"type": "radio",
"label": "Other",
"value": 13,
"subFields": [
"id": "question_2a",
"type": "string",
"condition":
"type": "BinaryExpression",
"operator": "==",
"left":
"type": "Identifier",
"name": "question_2"
,
"right":
"type": "Literal",
"value": 13
]
]
"id": "question_2_b",
"type": "radioGroup",
"description": "Description3",
"anwers": [
"type": "radio",
"label": "Label - Radio 1",
"value": 1
,
"type": "radio",
"label": "Label - Radio 2",
"value": 2
,
"type": "radio",
"label": "Label - Radio 3",
"value": 3
]
"id": "question_3",
"type": "radioGroup",
"description": "Description3",
"anwers": [
"type": "radio",
"label": "Yes",
"value": 1
,
"type": "radio",
"label": "No",
"value": 0
]
我的问题是我不知道如何删除这些部分:
"uiComponent": "SmallContent",
"componentProps":
"text": "* If the answer to the above question is “Yes”, please contact the Support immediately."
和
"subFields": [
"id": "question_2a",
"type": "string",
"condition":
"type": "BinaryExpression",
"operator": "==",
"left":
"type": "Identifier",
"name": "question_2"
,
"right":
"type": "Literal",
"value": 13
]
我只为 question_3 玩了一点这个 jq:
jq play 2
.subFields[] | id: .id, title: .title, description: .description, type: .type, subFields: .subFields | select(has("id") and .id != null) | select(.id=="question_3") | id: .id, title: .title, description: .description, type: .type, questions: (.subFields[]|join(","))
并产生了这个结果:
"id": "question_3",
"title": "Title3",
"description": "Description3",
"type": "radioGroup",
"questions": "radio,Yes,1"
"id": "question_3",
"title": "Title3",
"description": "Description3",
"type": "radioGroup",
"questions": "radio,No,0"
还有
jq play 3
.subFields[] | id: .id, title: .title, description: .description, type: .type, subFields: .subFields | select(has("id") and .id != null) | select(.id=="question_3") | [.id, .title, .description, .type, (.subFields[]|join(","))]
结果:
[
"question_3",
"Title3",
"Description3",
"radioGroup",
"radio,Yes,1",
"radio,No,0"
]
你能帮我改进我创建的那些 JQ 模式以获得预期的结果吗?
提前致谢!
【问题讨论】:
【参考方案1】:以下产生您的第一个替代方案:
.subFields[]
| select(.id?)
| id, title, description, type +
(.subFields[]
| select(.type?)
| [.type,.label,.value] | join(",")
| questions: . )
注意两个 select()
过滤器。
此处明确指定了键名,以确保遵循您指定的顺序。
【讨论】:
以上是关于通过按键过滤数组,使用 jq 展平 JSON 文档的主要内容,如果未能解决你的问题,请参考以下文章