json 如何根据数组中的值在JQ中选择项目

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25649960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:31:20  来源:igfitidea点击:

How to select items in JQ based on value in array

jsonjq

提问by K2xL

I have a file with lines like this:

我有一个这样的行的文件:

{"items":["blue","green"]}
{"items":["yellow","green"]}
{"items":["blue","pink"]}

How can I use jqto select and show only the JSON values that have "blue" in their "items" array?

如何使用jq选择并仅显示“项目”数组中具有“蓝色”的 JSON 值?

So the output would be:

所以输出将是:

{"items":["blue","green"]}
{"items":["blue","pink"]}

采纳答案by K2xL

Found out the answer

找到了答案

jq 'select(.items | index("blue"))'

回答by peak

On Jan 30, 2017, a builtin named INwas added for efficiently testing whether a JSON entity is contained in a stream. It can also be used for efficiently testing membership in an array. In the present case, the relevant usage would be:

2017 年 1 月 30 日,IN添加了一个名为的内置函数,用于高效测试流中是否包含 JSON 实体。它还可用于有效测试数组中的成员资格。在本案中,相关用法为:

select( .items as $items | "blue" | IN($items[]) )

If your jq does not have IN/1, then so long as your jq has first/1, you can use this equivalent definition:

如果您的 jq 没有IN/1,那么只要您的 jq 有first/1,您就可以使用以下等效定义:

def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;

any/0

任何/0

Using any/0here is relatively inefficient, e.g. compared to using any/1:

any/0在这里使用效率相对较低,例如与使用相比any/1

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

(In practice, index/1is usually fast enough, but its implementation currently (jq 1.5 and versions through at least July 2017) is suboptimal.)

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

回答by Jeff Mercado

While what you have certainly works, it would be more correct to use contains. I would avoid that use since it can lead to confusion. index("blue")is 0and one wouldn't consider that a truthy value and might expect it to be excluded from the results.

虽然您所拥有的肯定有效,但使用contains. 我会避免这种使用,因为它会导致混乱。 index("blue")0并且人们不会认为这是一个真实值,并可能期望它被排除在结果之外。

Consider using this filter instead:

select(.items | contains(["blue"]))

考虑改用这个过滤器:

select(.items | contains(["blue"]))

This has the added benefit that it would work if you wanted items with more than one match by simply adding more to the array.

这有一个额外的好处,如果您希望通过简单地向数组添加多个匹配项来获得多个匹配项,它将起作用。

As Will pointed out in the comments, this isn't quite correct. Strings are compared using substring matching (containsis used recursively) here.

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

In retrospect, containsdidn't work out as I thought it would. Using indexworks, but personally I wouldn't use it. There's something about figuring out if an item is in a collection by looking for it's index that feels wrong to me. Using containsmakes more sense to me, but in light of this information, it wouldn't be ideal in this case.

回想起来,contains并没有像我想象的那样成功。使用index作品,但我个人不会使用它。通过查找我觉得不对的索引来确定一个项目是否在集合中是有一些事情的。使用contains对我来说更有意义,但根据这些信息,在这种情况下它并不理想。



Here's an alternative that should work correctly:

这是一个应该可以正常工作的替代方法:

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

Or for a more scalable way if you wanted to be able to match more values:

或者,如果您希望能够匹配更多值,则采用更具可扩展性的方式:

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

回答by Juan Miguel Díaz Pérez

I have needed to use 'regex' for the same situation of the objects. (In another context, of course). I write the code because I did not find a solution for my need in these pages. This can be useful for someone.

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

For example, to match the blue color using a regular expression:

例如,要使用正则表达式匹配蓝色:

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

jqPlay

播放