首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获取包含已知对象的json子树

问如何获取包含已知对象的json子树
EN

Stack Overflow用户
提问于 2020-04-02 11:29:52
回答 2查看 635关注 0票数 1

我想用i3-msg -t get_tree和jq从jq中提取包含聚焦窗口的子树。我知道焦点窗口可以用

i3-msg -t get_tree | jq ".. | (.nodes? // empty)[] | select(.focused == true)"

一个简单的例子是:

代码语言:javascript
复制
{
  "node": [
    {
      "node": {
        "foo": "bar"
      }
    },
    {
      "node": {
        "foo": "foo"
      }
    }
  ]
}

如果搜索一个包含node的.foo == "bar",则输出应该返回

代码语言:javascript
复制
{
  "node": [
    {
      "node": {
        "foo": "bar"
      }
    }
  ]
}

但是,我似乎找不到一种适当的方法来提取从根到这个节点的子树。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-06 22:12:19

代码语言:javascript
复制
.node |= map(select(.node.foo == "bar"))

这个概念被称为更新分配

票数 2
EN

Stack Overflow用户

发布于 2020-04-08 21:03:53

最初的问题有两个不同的子问题,一个是关于..的使用,而不是引用一个已发布的JSON示例,另一个是基于特定类型的JSON输入。此响应使用一种基于使用paths的策略,大致如下:

代码语言:javascript
复制
reduce pv as [$p,$v] (null; setpath($p; $v))

这可以根据需要处理数组,也可以不处理数组,这部分取决于所需的内容。如果数组中的null值一般不需要,那么按以下方式向walk/1添加一个调用是合适的:

代码语言:javascript
复制
walk(if type == "array" then map(select(. != null)) else . end)

或者,如果必须保留原件中的null值,则可以使用下面附录中详细说明的策略。

(1)以使用..。

代码语言:javascript
复制
def pv:
 paths as $p
 | getpath($p)
 | . as $v
 | (.nodes? // empty)[] | select(.focused == true)
 | [$p,$v];

reduce pv as [$p,$v] (null; setpath($p; $v))

如上所述,要消除所有数组中的所有空值,可以调整对walk/1的调用。否则,如果null值由setpath插入数组以保留原始结构的各个方面,请参见下面的附录。

(2)对于示例JSON,以下内容就足够了:

代码语言:javascript
复制
def pv:
 paths as $p
 | getpath($p)
 | . as $v
 | (.node? // empty) | select(.foo == "bar")
 | [$p,$v];

reduce pv as [$p,$v] (null; setpath($p; $v))

对于给定的样本,这将产生:

代码语言:javascript
复制
{"node":[{"node":{"foo":"bar"}}]}

对于类似的输入,如果想要从数组中消除null值,只需像前面一样轻敲对walk/1的调用;也请参阅下面的附录。

附录

如果不希望null值被setpath插入数组以保留原始结构,最简单的方法是将原始JSON中的null值更改为一些独特的值(例如":null:"),执行选择,修剪null值,然后将特殊值转换回null。

示例

例如,考虑foo/bar示例的这个变体:

代码语言:javascript
复制
{
  "node": [
    {
      "node": {
        "foo": "foo0"
      }
    },
    {
      "node": {
        "foo": "bar",
        "trouble": [
          null,
          1,
          null
        ]
      }
    },
    {
      "node": {
        "foo": "foo1"
      }
    },
    {
      "node": {
        "foo": "bar",
        "trouble": [
          1,
          2,
          3
        ]
      }
    }
  ],
  "nodes": [
    {
      "node": {
        "foo": "foo0"
      }
    },
    {
      "node": {
        "foo": "bar",
        "trouble": [
          null,
          1,
          null
        ]
      }
    }
  ]
}

使用":null:“作为独特的值,可以使用以前在这种情况下显示的”主“程序的以下变体:

代码语言:javascript
复制
walk(if type == "array" then map(if . == null then ":null:" else . end) else . end)
| reduce pv as [$p,$v] (null; setpath($p; $v))
| walk(if type == "array"
       then map(select(. != null) | if . == ":null:" then null else . end)
       else . end)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60990532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档