我有这个输入JSON
[{
"Name":"Wolfenstein",
"24 Hour":"FALSE",
"Shop 1":"TRUE",
"Shop 2":"FALSE",
}]
并希望将所有“FALSE”和“TRUE”值分别更改为false
和true
。
[{
"Name":"Wolfenstein",
"24 Hour":false,
"Shop 1":true,
"Shop 2":false,
}]
作为奖励,我只想选择那些键以“Shop”开头且至少将“Shop”设置为“TRUE”的数组项。 什么是jq过滤器?
答案 0 :(得分:2)
您的总体要求不明确,但如果您真的想以您建议的方式更新任意JSON文本,则可能需要考虑使用walk
。但是为了简单起见,我假设你只是拥有一个你所展示的那种对象数组。
让我们从简单的任务开始,将TRUE / FALSE更改为true / false。这可以直接完成如下:
map( map_values(if . == "TRUE" then true
elif . == "FALSE" then false
else .
end) )
但是因为你的至少一个" Shop"设置为" TRUE"'要求,定义辅助功能会很有帮助:
def toboolean:
if . == "TRUE" then true
elif . == "FALSE" then false
else .
end;
所以第一项任务可以通过以下方式完成:
map(map_values(toboolean))
现在我们很高兴。假设您的jq有any/2
,并根据您的总体要求进行解释,我们可以写:
map( if any( to_entries[];
(.key|startswith("Shop")) and .value=="TRUE" )
then map_values(toboolean)
else .
end)
或者只是" Shop"价值要改变:
map( if any( to_entries[];
(.key|startswith("Shop")) and .value=="TRUE" )
then with_entries( if .key|startswith("Shop")
then .value |= toboolean
else .
end)
else .
end)
如果您的jq没有any/2
,请考虑升级;如果这不是一个选项,您可以使用reduce
编写自己的(低效)版本。
上述解决方案可以使用通用函数when/2
进行简化,定义为:
def when(filter; action): if filter//null then action else . end;
例如,上面的八行解决方案变成了这个四线程,一旦熟悉when/2
,它也可能更容易阅读:
map( when( any( to_entries[];
(.key|startswith("Shop")) and .value=="TRUE" );
with_entries( when( .key|startswith("Shop");
.value |= toboolean) ) ))