Json 如何根据数组中的值选择JQ中的项

Json 如何根据数组中的值选择JQ中的项,json,jq,Json,Jq,我有一个文件,上面有这样的行: {"items":["blue","green"]} {"items":["yellow","green"]} {"items":["blue","pink"]} 如何使用来选择并仅显示其“items”数组中包含“blue”的JSON值 因此,输出将是: {"items":["blue","green"]} {"items":["blue","pink"]} select( .items as $items | "blue" | IN($items[]) )

我有一个文件,上面有这样的行:

{"items":["blue","green"]}
{"items":["yellow","green"]}
{"items":["blue","pink"]}
如何使用来选择并仅显示其“items”数组中包含“blue”的JSON值

因此,输出将是:

{"items":["blue","green"]}
{"items":["blue","pink"]}
select( .items as $items | "blue" | IN($items[]) )
找到答案了吗

jq 'select(.items | index("blue"))'
虽然您所拥有的确实有效,但使用
contains
更为正确。我会避免这种用法,因为它会导致混淆<代码>索引(“蓝色”)< /代码>是代码> 0 。一个不会考虑一个真实的值,并期望它被排除在结果之外。

请考虑改用此筛选器:

select(.items | contains(["blue"]))
这样做的另一个好处是,如果您希望通过向数组中添加更多匹配项来获得具有多个匹配项的项,那么它将起作用。

正如威尔在评论中指出的,这并不完全正确。这里使用子字符串匹配比较字符串(
contains
递归使用)

回想起来,
contains
并不像我想象的那样有效。使用
索引
是可行的,但就我个人而言,我不会使用它。通过查找我觉得不对的索引,可以判断某个项目是否在集合中。使用
contains
对我来说更有意义,但鉴于这些信息,在这种情况下并不理想


这里有一个可以正常工作的替代方案:

select([.items[] == "blue"] | any)
或者,如果您希望能够匹配更多值,可以采用更具可扩展性的方式:

select(.items as $values | ["blue", "yellow"] | map([$values[] == .] | any) | all)

2017年1月30日,在中添加了一个名为的内置代码,用于有效测试流中是否包含JSON实体。它还可以用于有效地测试阵列中的成员资格。在目前情况下,相关用途为:

{"items":["blue","green"]}
{"items":["blue","pink"]}
select( .items as $items | "blue" | IN($items[]) )
如果您的jq在/1中没有
,那么只要您的jq有
第一个/1
,您就可以使用此等效定义:

def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;
任何/0 此处使用
any/0
效率相对较低,例如,与使用
any/1
相比:

select( any( .items[]; . == "blue" ))

(在实践中,
index/1
通常足够快,但目前它的实现(jq 1.5和至少到2017年7月的版本)并不理想。)

对于对象的相同情况,我需要使用“regex”。(当然,在另一种情况下)。我之所以编写代码,是因为我在这些页面中没有找到满足我需要的解决方案。这可能对某人有用

例如,要使用正则表达式匹配蓝色,请执行以下操作:

jq 'select(.items[]|test("bl.*"))' yourfile.json

这个答案不正确。虽然它在某些情况下(危险地)会起作用,但也可能导致误报。“contains”严格来说是一个子字符串搜索。反例:jq-n'[“foobar”,“bar”,“baz”]| contains([“foo”])”结果为true。比较:jq-n'[“foobar”,“bar”,“baz”]|(index(“foo”)==null | not)”,它正确地导致false。感谢您指出这一点,我没有意识到它会对数组递归运行过滤器。我确信有一种方法可以在保持可伸缩性的同时做到这一点。我不知道这是否是可伸缩的,因为我怀疑在所有情况下都会执行迭代搜索,但我以前也使用过:
jq-n'[“foobar”,“bar”,“baz”]|[]|选择(.==“foobar”)]| length>0'
,它至少有可能并行运行搜索。这是迄今为止我发现的最好的解决方案,用于处理将单个列表项作为字符串且不可迭代的数据。请注意,这不完全匹配。