将json中的所有“TRUE”和“FALSE”值替换为各自的布尔值

时间:2017-03-09 21:23:58

标签: json jq

我有这个输入JSON

[{
   "Name":"Wolfenstein",
   "24 Hour":"FALSE",
   "Shop 1":"TRUE",
   "Shop 2":"FALSE",
}]

并希望将所有“FALSE”和“TRUE”值分别更改为falsetrue

[{
   "Name":"Wolfenstein",
   "24 Hour":false,
   "Shop 1":true,
   "Shop 2":false,
}]

作为奖励,我只想选择那些键以“Shop”开头且至少将“Shop”设置为“TRUE”的数组项。 什么是jq过滤器?

1 个答案:

答案 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编写自己的(低效)版本。

使用时/ 2

上述解决方案可以使用通用函数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) ) ))