Select entries based on multiple values in jq

北城以北 提交于 2019-12-05 21:48:16

inside and contains are a bit weird. Here are some more straightforward solutions:

index/1

select( .author as $a | ["Gary", "Larry"] | index($a) )

any/2

["Gary", "Larry"] as $whitelist
| select( .author as $a | any( $whitelist[]; . == $a) )

Using a dictionary

If performance is an issue and if "author" is always a string, then a solution along the lines suggested by @JeffMercado should be considered. Here is a variant (to be used with the -n command-line option):

["Gary", "Larry"] as $whitelist
| ($whitelist | map( {(.): true} ) | add) as $dictionary
| inputs
| select($dictionary[.author])

IRC user gnomon answered this on the jq channel as follows:

jq 'select([.author] | inside(["Larry", "Garry", "Jerry"]))'

The intuition behind this approach, as stated by the user was: "Literally your idea, only wrapping .author as [.author] to coerce it into being a single-item array so inside() will work on it." This answer produces the desired result of filtering for a series of names provided in a list as the original question desired.

You can use objects as if they're sets to test for membership. Methods operating on arrays will be inefficient, especially if the array may be huge.

You can build up a set of values prior to reading your input, then use the set to filter your inputs.

$ jq -n --argjson names '["Larry","Garry","Jerry"]' '
(reduce $names[] as $name ({}; .[$name] = true)) as $set
    | inputs | select($set[.author])
' blah.json
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!