首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JSONPath union "[,]“等价于GPath

JSONPath union "[,]“等价于GPath
EN

Stack Overflow用户
提问于 2022-04-03 14:31:27
回答 2查看 72关注 0票数 0

考虑给予JSON

代码语言:javascript
复制
{
  "data": {
    "array": [
      {
        "foo": {"a": "1 foo a", "b": "2 foo b", "c": 512},
        "bar": {"a": "3 bar a", "b": "4 bar b"},
        "baz": {"a": "5 baz a", "b": "6 baz b", "d": 75},
        "other": {"a": 2, "x": 13, "y": 44},
      },
      {
        "foo": {"a": "7 foo a", "b": "8 foo b"},
        "bar": {"a": "9 bar a", "b": "10 bar b"},
        "baz": {"a": "11 baz a", "b": "12 baz b"},
        "other": {"a": 2, "x": 13, "y": 44, "z": 132},
      }
    ]
  }
}

使用简单的JSONPath,我可以按各自的顺序列出foos、bars和bazes中的所有foos和bs。

代码语言:javascript
复制
$.data.array[*][foo,bar,baz][a,b]
代码语言:javascript
复制
[
  "1 foo a", "2 foo b",
  "3 bar a", "4 bar b",
  "5 baz a", "6 baz b",
  "7 foo a", "8 foo b",
  "9 bar a", "10 bar b",
  "11 baz a", "12 baz b"
]

有使用Groovy GPath的方法吗?我想出的唯一可行的解决方案是:

代码语言:javascript
复制
def json = new JsonSlurper().parseText(jsonText)

json.data.array.foo.a
+ json.data.array.foo.b
+ json.data.array.bar.a
+ json.data.array.bar.b
+ json.data.array.baz.a
+ json.data.array.baz.b

但是结果仍然与JSONPath不同(顺序)

代码语言:javascript
复制
[1 foo a, 7 foo a,
 2 foo b, 8 foo b,
 3 bar a, 9 bar a,
 4 bar b, 10 bar b,
 5 baz a, 11 baz a, 
 6 baz b, 12 baz b]

附注:

我正在使用GPath进行我的放心测试,所以如果有其他方法来获得同样的结果,我会很高兴看到它。

P.P.S

实际上我找到了另一个解决方案

代码语言:javascript
复制
json.data.array
    *.subMap(["foo", "bar", "baz"])*.values().flatten()
    *.subMap(["a", "b"])*.values().flatten()

产生与JSONPath相同的结果。

代码语言:javascript
复制
[1 foo a, 2 foo b,
 3 bar a, 4 bar b,
 5 baz a, 6 baz b,
 7 foo a, 8 foo b,
 9 bar a, 10 bar b,
 11 baz a, 12 baz b]

但在JSONPath,它仍然不是工会运作的替代方案。例如,还有另一个更复杂的表达式:

代码语言:javascript
复制
$.data.array[*][foo,bar,?(@.a == '11 baz a')][a,b]

GPath的替代方案与上面的subMap解决方案完全不同。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-19 09:37:58

多亏了@肖,我找到了最接近JsonPath的解决方案:

代码语言:javascript
复制
def json = new JsonSlurper().parseText(input) //text is your json string

def result = json.data.array
        .collectMany { [it.foo, it.bar, it.baz] }
        .collectMany { [it.a, it.b] }

println result // [1 foo a, 2 foo b, 3 bar a, 4 bar b, 5 baz a, 6 baz b, 7 foo a, 8 foo b, 9 bar a, 10 bar b, 11 baz a, 12 baz b]

但是,如果我想要替代

代码语言:javascript
复制
$.data.array[*][foo,bar,?(@.a == '11 baz a')][a,b]

其结果是更加肮脏:

代码语言:javascript
复制
def result = json.data.array
        .collectMany {
            [it.foo, it.bar] + (it.baz.a == '11 baz a' ? it.baz : [])
        }
        .collectMany { [it.a, it.b] }

我认为,如果我们忽略了使用过滤器,collectMany可以被视为等同于[,]

欢迎您的过滤联盟版本。

票数 0
EN

Stack Overflow用户

发布于 2022-05-14 13:19:59

下面是使用collectMany收集方法解决问题的纯gpath版本:

根据RomanMitasov最新问题的最新答复:

代码语言:javascript
复制
def json = new JsonSlurper().parseText(text) //text is your json string
def result = json.data.array*.collectMany{k,v-> k in ["foo","bar","baz"]? v.collect{k1,v1-> k1 in ["a","b"]? v1:[]}:[]}.flatten()
println result //[1 foo a, 2 foo b, 3 bar a, 4 bar b, 5 baz a, 6 baz b, 7 foo a, 8 foo b, 9 bar a, 10 bar b, 11 baz a, 12 baz b]

原来的答案:

代码语言:javascript
复制
def json = new JsonSlurper().parseText(text) //text is your json string
def result = json.data.array*.collectMany{k,v->v.collect{it.value}}.flatten()
println result //[1 foo a, 2 foo b, 3 bar a, 4 bar b, 5 baz a, 6 baz b, 7 foo a, 8 foo b, 9 bar a, 10 bar b, 11 baz a, 12 baz b]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71726821

复制
相关文章

相似问题

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