【问题标题】:Display an object if a nephew element array contains a value如果侄子元素数组包含值,则显示对象
【发布时间】:2020-12-21 06:28:29
【问题描述】:

Select objects based on value of variable in object using jq

这说明了如何直接在选择条件之上返回值,但是我如何获得与我的选择条件之上的值相邻的另一个对象?

鉴于以下数据,什么 jq 调用会返回其卫星已被破坏的行星的法语名称? (这是我正在使用的实时数据的结构复制——它实际上以这种方式使用“值”这个词,所以这没有帮助)

{"kind":"solarsystem","name":"Sol",
"Planets": [
 { "kind":"habitable",
  "names": { "english":"Earth","french":"Terre"},
  "satellites" : [
    {"name":"The Moon",
     "parameters": [
       {"name":"diameter", "intValue":"3476"},
       {"name":"diameter_units", "value":"km"},
       {"name":"unspoiled","value":"no"}]}]},
 {"kind":"uninhabitable",
  "names": {"english":"Mars","french":"Mars"},
  "satellites" : [
    {"name":"Phobos",
     "parameters": [
       {"name":"diameter", "intValue":"2200"},
       {"name":"diameter_units", "value":"m"},
       {"name":"unspoiled","value":"yes"}]},
    {"name":"Deimos",
     "parameters": [
       {"name":"diameter", "intValue":"1200"},
       {"name":"diameter_units", "value":"m"},
       {"name":"unspoiled","value":"yes"}]}]}]}

【问题讨论】:

  • 识别have been spoiled?的标准是什么,即上述帖子中没有名称为"spoiled"的json记录
  • 再看一眼,你的意思是{"name":"unspoiled","value":"no"}作为标准吗?
  • 谢谢!我认为这将是简单但强大的。是的,我本可以更好地措辞;我试图想出一些重复我的数据结构的东西。它读起来像不要做唐尼不做的事

标签: json select jq


【解决方案1】:

下面的程序选择了卫星都被破坏的行星。由于每个 parameter 都是一个名称-值对,我们可以使用 from_entries 将参数数组转换为一个对象,并仅使用 .unspoiled 检索 unspoiled 状态,从而避免使用另一个select 来查找我们感兴趣的参数。

.Planets[] | select(.satellites | all(.parameters | from_entries .unspoiled == "no")) .names.french

如果一个被宠坏的月亮就足够了,请将all 更改为any

Online demo

【讨论】:

    【解决方案2】:

    在这里,还有一个使用替代工具 (jtc) 的相同 JSON 查询的解决方案:

    在最简单的形式中,以下是可行的:

    bash $ <file.json jtc -w'[value]:<no>:[-5][names][french]'
    "Terre"
    

    但是,该解决方案将为每个月亮返回行星的法语名称,例如,对于被损坏的卫星,它会给出:

    bash $ <file.json jtc -w'[value]:<yes>:[-5][names][french]'
    "Mars"
    "Mars"
    bash $ 
    

    对于有多个卫星但名称只需要一次的情况,像这样加强查询(这里展示被宠坏的卫星):

    bash $ <file.json jtc -w'<satellites>l:[value]:<yes>[-5][names][french]'
    "Mars"
    bash $ 
    

    PS。我是jtc unix JSON 处理器的开发者
    聚苯乙烯。 SO要求上述免责声明。

    更新:

    根据 cmets 中与 @oguzismail 的讨论更新了答案,以增强 valuefrench 标签之间的结构关系,以便其他(不相关)可能的 value 匹配不会触发误报。
    如果偶然地,结构关系[-5][names] 不够,则可以通过在[value]... 词位之前插入&lt;unspoiled&gt;[-1] 来最终增强查询

    【讨论】:

    • 在我投票之前,-5 是干什么用的?你没有硬编码参数unspoiled的索引,对吧?
    • Oguz,在jtc 中,负索引提供了从当前找到的元素到根的父级寻址。例如:-1 表示直接父级,-2 - 父级的父级,等等。对于给定的数据结构,-5 是到达找到的value 元素到持有french 的父级所需的深度。考虑到这个 JSON 的结构是固定的,硬编码 depth 参数是安全的。
    • 我同意它是。困扰我的是我在任何这些调用中都看不到unspoiled。 OP 的示例不包含任何参数也将是/否作为值,但我不确定假设实际数据与问题中的示例一致是否也是安全的。
    • 答案是根据给定的样本提供的。如果原始 JSON 在 JSON 的其他部分包含 value 标签,则可以通过添加 &lt;unspoiled&gt;[-1] 来轻松增强查询
    • 现在很好,如果我是你,我会把它包含在我的答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 2018-07-17
    • 2021-07-19
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多