假设我得到了一个API响应,它看起来有点像这样:
{
"results": [
{
"name": "foobar",
"description": "it's the foobar 1000 baby!"
},
{
"name": "another_thing",
"description": "acme 1000 whizbang machine"
}
]
}
我将这个对象通过管道传递给过滤器.results[] | select(.name == "foobar").description
,但我并不十分确信我已经完全正确地编写了select()
过滤器。如何Assertselect()
过滤器按预期运行,并返回1个结果?
5条答案
按热度按时间1qczuiv01#
如果你有一个数组,使用
map(select(f))
模式可能更简单:或者:
dw1jzc5e2#
select()
过滤器发出一个(可能是空的)JSON对象流,* 而不是 * 一个JSON对象数组。因此,虽然我们可以使用length
来做这样的Assert,但我们必须巧妙地使用它:当然,你可以做任何你喜欢的事情,而不是提高错误。
其工作方式是将
select()
过滤器返回的对象流 Package 在一个数组中,这样后续的length
过滤器就不会单独对每个对象进行操作,而是对对象列表进行操作。如果Assert通过,为了方便调用者,我们使用.[]
再次展开数组。xytpbqjk3#
有各种函数可以过滤输入流,只保留某些结果或给定数量的结果,而丢弃其他结果。
(静默地)丢弃第二个和所有后续结果(即只得到第一个或什么都不得到),使用
first(f)
作为suggested by @peak。对于前n个结果,有一个广义的limit($n; f)
过滤器,它为您提供所有结果,直到第n个,即最多n个项目的流,因此limit(1; f)
将像first(f)
一样。请注意,如果流一开始是空的,这些过滤器(正确地)什么也不产生。您可以使用isempty(f)
来测试这种情况,它会产生一个预期的布尔值。要主动Assert精确(或最小或最大)数量的结果,即如果失败了就采取行动,而不是将所有项收集到一个消耗内存的数组中,只是为了查询它的长度,您可以使用
reduce
计算流的大小,并根据结果的评估采取行动。这里有一个函数,它接受一个数字,一个被复制的输入流(未改变,即作为流),而如果计数失败则产生另一个过滤器。(将用于精确匹配的==
替换为<
、<=
、>
、>=
之一,以打开上限或下限。应用于您的测试用例:
你可以进一步推广这种方法,例如:将所述计数结果提供给定制函数。
qni6mghb4#
如果你想要一个保证不会产生多个结果的表达式,使用
first/1
。如果你想要一个保证只产生一个结果的表达式,假设没有错误阻止至少一个结果,你可能可以将
first
与//
结合使用。当然,在这种情况下,您必须指定所需的值,以防底层查询没有结果。下面是一个例子:
一个可能仍然可以接受的更简单的替代方案是:
vqlkdk9b5#
这里有一个“Assert”风格的过滤器,您可以使用它来避免收集所有结果:
使用示例: