json 如何在迭代值之前检查jq中是否存在'key'

rks48beu  于 2023-04-22  发布在  其他
关注(0)|答案(5)|浏览(106)

我从下面的查询中得到Cannot iterate over null (null),因为.property_history不在result对象中。
如何在继续使用map(...)之前检查.property_history密钥的存在?
我尝试使用类似sold_year=echo "$content" | jq 'if has("property_history") then map(select(.event_name == "Sold"))[0].date' else null end`的东西

原始查询:

sold_year=`echo "$content" | jq '.result.property_history | map(select(.event_name == "Sold"))[0].date'`

JSON:

{  
   "result":{  
      "property_history":[  
         {  
            "date":"01/27/2016",
            "price_changed":0,
            "price":899750,
            "event_name":"Listed",
            "sqft":0
         },
         {  
            "date":"12/15/2015",
            "price_changed":0,
            "price":899750,
            "event_name":"Listed",
            "sqft":2357
         },
         {  
            "date":"08/30/2004",
            "price_changed":0,
            "price":739000,
            "event_name":"Sold",
            "sqft":2357
         }
      ]
   }
}
nbnkbykc

nbnkbykc1#

您可以在jq中使用select-expression来实现您想要实现的功能,例如:

jq '.result 
  | select(.property_history != null) 
  | .property_history 
  | map(select(.event_name == "Sold"))[0].date'
vybvopom

vybvopom2#

从技术上讲,要测试属性的存在,您应该使用has/1,但在当前上下文中,使用后缀?操作符可能更好,例如:

$ jq '.result 
  | .property_history[]?
  | select(.event_name == "Sold") 
  | .date'
"08/30/2004"

如果.result的值有可能不是JSON对象,那么可以将上面的第二行替换为:

try(.property_history[])
mm5n2pyu

mm5n2pyu3#

使用has("mykey1")(对象)或has(0)(数组):

jq 'has("name")' <<< "{\"name\": \"hello\"}"

输出:

true
t30tvxxf

t30tvxxf4#

技巧是将//与empty一起使用:

jq '.result.property_history // empty | map(select(.event_name == "Sold"))[0:1][].date'

另一种方法是使用额外的select:

jq '.result.property_history | select(.) | map(select(.event_name == "Sold"))[0:1][].date'
webghufk

webghufk5#

一般模式:

try (...) // "default_value"

你的逻辑:

jq 'try (.result.property_history | map(select(.event_name == "Sold"))[0].date) // "default_value"'

try(没有catch)如果表达式失败则返回空。如果值为空,则//提供默认值。

相关问题