0

问:如何防止 JSONata 在数组构造函数中“自动展平”数组?

给定 JSON 数据:

{
  "w" : true,
  "x":["a", "b"],
  "y":[1, 2, 3],
  "z": 9
}

JSONata 查询似乎选择了 4 个值:

[$.w, $.x, $.y, $.z]

$.x 和 $.y 的嵌套数组被展平/内联到我的外包装中,导致超过 4 个值:

[ true, "a", "b", 1, 2, 3, 9 ]

我想达到的结果是

[ true, ["a", "b"], [1, 2, 3], 9 ]

我可以通过使用来实现这一点

[$.w, [$.x], [$.y], $.z]

但这需要我先验地知道$.x 和 $.y 是数组。

我想选择 4 个值并让结果数组恰好包含 4 个值,与所选值的类型无关。

显然,关于 JSONata 序列和数组之间的交互,有些事情我无法理解。

4

3 回答 3

1

与 XPath/XQuery 序列一样,它将路径表达式的结果展平到输出数组中。在您的示例中,可以通过使用$each高阶函数迭代对象的键/值对来避免这种情况。以下表达式将获得您想要的结果,而不会使结果变平:

$each($, function($v) {
  $v
})

只是返回对象中每个属性的值。

更新:为您更新的问题扩展此答案:我认为这与以前的github 问题有关,关于如何将多个独立查询组合到同一个问题中。这使用一个对象以与您到达的方式类似的方式保存所有查询。也许更清晰的表达是这样的:

{
  "1":  t,
  "2": u.i,
  "3": u.j,
  "4": u.k,
  "5": u.l,
  "6": v
} ~> $each(λ($v){$v})

Theλ只是 的简写function,如果您可以在键盘上找到它(JSONata 练习器中的 F12)。

于 2018-04-04T16:12:51.510 回答
0

我正在努力改写我的问题,以便描述我在使用 JSONata 的类似序列的数组处理时遇到的困难。

我需要运行多个查询以从同一个 JSON 树中提取多个值。我想构建一个 JSONata 查询表达式,它提取n 个数据项(或运行n个子查询)并在有序数组中准确返回n 个值。

此示例似乎查询请求 6 个值,但由于数组展平,结果数组没有 6 个值。

此示例将每个查询显式包装在数组构造函数中,以便结果具有 6 个值。但是,不是数组的值被包装在一个无关紧要的和不受欢迎的数组中。此外,无法确定原始类型是什么......

这个例子显示了我试图完成的结果......我要求了 6 件事,我得到了 6 个值。但是,我必须知道要获取的值的数据类型,并将数组显式包装在数组构造函数中以解决序列展平问题。

这个例子显示了我想要的。我在不知道数据类型的情况下查询了 6 件事并得到了 6 个答案。但是我必须引入一个对象作为临时容器才能解决数组展平行为。

我没有找到任何谓词可以让我在查询中测试值的类型......这可能让我使用 ?: 运算符来动态决定是否将数组包装在数组构造函数中。例如 $isArray($.foo) ?[$.foo] : $.foo

问:我是否有更简单的方法(有效地)提交 6 个“路径”查询并在有序数组中取回 6 个值,而无需知道我正在查询的值的数据类型?

于 2018-04-05T03:36:36.960 回答
0

基于 Acoleman 的示例,这是一种传入n“查询”字符串(表示路径)的方法:

(['t', 'u.i', 'u.j', 'u.k', 'u.l', 'v'] {
    $: $eval('$$.' & $)
}).$each(function($o) {$o})

n并以原始数据格式取回一组结果:

[
  12345,
  [
    "i",
    "ii",
    "iii"
  ],
  [],
  "K",
  {
    "L": "LL"
  },
  null
]

似乎使用$each是避免任何扁平化的唯一方法......

当然,这可能不是最有效的表达式,因为每个表达式都必须从从数据结构的根开始的路径字符串进行评估——但是你去吧。

于 2021-08-27T16:04:33.537 回答