Arrays 如何将命名列表转换为对象数组
我有一些数据看起来像这样Arrays 如何将命名列表转换为对象数组,arrays,json,iteration,jq,Arrays,Json,Iteration,Jq,我有一些数据看起来像这样 { "type1": [ "a", "b" ], "type2": [ "c", "d" ], "type3": "x" } 我想把它转换成 [ {"value": "a", "type": "type1" }, {"value": "b", "type": "type1" }, {"value": "c", "type": "type2" }, {"value": "d"
{
"type1": [
"a", "b"
],
"type2": [
"c", "d"
],
"type3": "x"
}
我想把它转换成
[
{"value": "a", "type": "type1" },
{"value": "b", "type": "type1" },
{"value": "c", "type": "type2" },
{"value": "d", "type": "type2" },
{"value": "x", "type": "type3" },
]
数组元素可以有一个或多个值。使用jq是否可能做到这一点
我能够处理非数组元素,但我的表达式只保留列表中的最后一项
to_entries
| map_values({value:[.value]|flatten, type:.key})
| map_values({value:.value[], type:.type})
我得到这个结果,其中元素“b”和“d”被排除在结果之外
[
{
"value": "a",
"type": "type1"
},
{
"value": "c",
"type": "type2"
},
{
"value": "x",
"type": "type3"
}
]
我能够用以下方法解决这个问题
- 将项转换为键值对
- 将值转换为数组并展平
- 映射每个项目
- 在变量中存储类型
- 映射数组中的每个值,添加type属性
- 展平嵌套数组
我将您的数据放在d.json中,并将其放在d.jq中:
# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2
[
.
|to_entries[]
|.key as $k
|(
(.value|strings|{"type":($k),"value":.}),
(.value|arrays|reduce .[] as $i ( []; . += [ { "type": ($k), "value": $i } ] ) )[]
)
]
然后与jq一起运行
jq -f d.jq d.json
我知道一定有更好的办法:-)
但你最终会:
[
{
"type": "type1",
"value": "a"
},
{
"type": "type1",
"value": "b"
},
{
"type": "type2",
"value": "c"
},
{
"type": "type2",
"value": "d"
},
{
"type": "type3",
"value": "x"
}
]
以下是一个高效、简洁且可能是“规范”的解决方案:
[to_entries[]
| (if .value|type == "array" then {value: .value[]} else {value} end)
+ {type: .key} ]
或者,如果您更喜欢使用映射
,则可以使用等效方法:
to_entries
| map( (if .value|type == "array" then {value: .value[]}
else {value}
end)
+ {type: .key} )
这里的微妙之处在于,
{value:.value[]}
扩展为JSON对象流,就像:.value[]{value:.}
我更喜欢交替使用各种类型的过滤器,使其更紧凑。假设您只需要处理数组或标量的值,我会这样写:
[to_entries[]|{value:(.value | arrays[]/]),类型:.key}]
不要低估可以生成多个值的表达式的有用性,它可以使过滤器在有效使用时变得不那么复杂。
jq“$(cat d.jq)”d.json
应更改为jq-f d.jq d.json
。谢谢。如果我删除|字符串
,它也适用于对象。谢谢,我知道即使值是对象,这也能起作用。是的,这就是jq通用性的要点,没有复杂性!哇!短而整洁。
to_entries
| map( (if .value|type == "array" then {value: .value[]}
else {value}
end)
+ {type: .key} )