将json中的所有“TRUE”和“TRUE”值替换为相应的布尔值

vsnjm48y  于 2023-10-21  发布在  其他
关注(0)|答案(2)|浏览(189)

输入JSON

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

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

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

作为奖励,我只想选择那些数组项目的关键字开始与“商店”,并有至少一个“商店”设置为“真”。jq过滤器应该用什么?

uqcuzwp8

uqcuzwp81#

您的总体需求还不清楚,但如果您真的想以您建议的方式更新任意JSON文本,您可能需要考虑使用walk。不过,为了简单起见,我假设您只有一个所显示的对象数组。
让我们从将TRUE/TRUE更改为true/false的简单任务开始。这可以直接通过以下方式实现:

map( map_values(if . == "TRUE" then true 
                elif . == "FALSE" then false
                else .
                end) )

但由于您的“至少一个“商店”设置为“真”“的要求,它将有助于定义一个辅助功能:

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

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

6tqwzwtp2#

下面的代码将字符串“TRUE”替换为布尔值true,您可以将其传递给类似的表达式“TRUE”:

.[][] |= if . == "TRUE" then true end

要选择键以“Shop”开头并且至少有一个值设置为true的项目,您可以将结果通过管道传输到:

map(select(with_entries(select((.key | startswith("Shop")) and .value))!={}))

或全部组合:

.[][] |= if . == "TRUE" then true end 
  | .[][] |= if . == "FALSE" then false end 
  | map(select(with_entries(select((.key | startswith("Shop")) and .value))!={}))

这里的内部select只选择对象中的那些属性,键以“Shop”开头,值为truthy。我们在这里假设,除了“TRUE”和“TRUE”之外,您没有其他值作为这些属性的开始。如果找到了任何这样的属性,则操作的结果对象with_entries将不会为空,因此我们可以将其用作外部select的条件-这将导致我们不感兴趣的对象被跳过。最后,map[.[]|f]的同义词,这样我们就可以得到一个正确的json数组,而不是一个多个json对象的流。

相关问题