【问题标题】:jq: How do I reshape into an object, using multiple selects as values?jq:如何使用多个选择作为值重塑对象?
【发布时间】:2020-03-03 16:57:42
【问题描述】:

JSON

[
      {
        "name": "username",
        "value": "my-username"
      },
      {
        "name": "password",
        "value": "my-password"
      }
]

期望的结果

{ "username": "my-username", "password": "my-password" }

几次失败的尝试

.[] | { username: select(.name == "username").value, password: select(.name == "password").value }

没有输出

.[] | { username: select(.name == "username").value} + { password: select(.name == "password").value }

没有输出

.[] | { username: select(.name == "username").value } + .[] | { password: select(.name == "password").value }

失败

如果我只想要一个字段,则语法可以正常工作。例如

.[] | { username: select(.name == "username").value }

生产

{ "username": "my-username" }

唯一的问题是尝试对多个元素做同样的事情。

想法? 谢谢!

【问题讨论】:

    标签: json key jq


    【解决方案1】:

    碰巧,jq(1.5 或更高版本)已经理解了表示 JSON 对象的{"name":_, "value":_} 方法,因此您只需使用 jq 过滤器即可获得结果:

    from_entries
    

    【讨论】:

    • 谢谢@peak!当我读到这篇文章时,我已经接受了@hobbs 的回答,我很欣赏他详细介绍了我的方法的基本问题以及 .[] 的禅意。但是,您可能会争辩说,您针对 from_entries 的答案是一个更清晰、更直接的答案。
    【解决方案2】:

    如果您的表达式以 .[] | 开头,然后 | 之后的事物生成一个对象,那么您必须为数组的每个元素生成 0 或 1 个对象。但你知道那不是你想要的。你想要一个对象,所以你应该从生成一个对象开始。

    { 
        username: (.[] | select(.name == "username").value), 
        password: (.[] | select(.name == "password").value) 
    }
    

    与您当前正在执行的操作类似,但它有效。

    您也可以使用map({ key: .name, value }) | from_entries 作为更好的方法来做同样的事情:它使用jq 的内置from_entries 将键/值对数组转换为对象。您只需将name 密钥更改为key,这正是from_entries 所期望的。

    【讨论】:

    • 很好的答案!感谢您对.[] | 的澄清。除了提供获奖食谱。 from_entries 确实看起来正是我想要的,尤其是因为 namevalue 恰好已经是我的关键名称。顺便说一句,我也有兴趣制作{ "my-username": "my-password" }。我目前有.details.fields | from_entries | { (.username): .password } 工作,但我觉得我迈出的一步太多了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 2013-09-06
    相关资源
    最近更新 更多