jq - How to select objects based on a 'whitelist' of property values

喜夏-厌秋 提交于 2019-11-26 21:56:45

问题


Since an example is worth a thousand words, say I have the following JSON stream:

{"a": 0, "b": 1}
{"a": 2, "b": 2}
{"a": 7, "b": null}
{"a": 3, "b": 7}

How can I keep all the objects for which the .b property is one of [1, 7] (in reality the list is much longer so I don't want to do select(.b == 1 or .b == 7)). I'm looking for something like this: select(.b in [1, 7]), but I couldn't find what I'm looking for in the man page.


回答1:


Doing $value in $collection could be achieved using the pattern select($value == $collection[]). A more efficient alternative would be select(any($value == $collection[]; .)) So your filter should be this:

[1, 7] as $whitelist | select(any(.b == $whitelist[]; .))

Having the array in a variable has its benefits as it lets you change the whitelist easily using arguments.

$ jq --argjson whitelist '[2, 7]' 'select(any(.b == $whitelist[]; .))'



回答2:


The following approach using index/1 is similar to what was originally sought (".b in [1, 7]"), and might be noticeably faster than using .[] within select if the whitelist is large.

If your jq supports --argjson:

jq --argjson w '[1,7]' '. as $in | select($w | index($in.b))'

Otherwise:

jq --arg w '[1,7]' '. as $in | ($w|fromjson) as $w | select($w | index($in.b))'

or:

jq '. as $in | select([1, 7] | index($in.b))'

UPDATE

On Jan 30, 2017, a builtin named IN was 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. For example, the above invocation with --argjson can be simplified to:

jq --argjson w '[1,7]' 'select( .b | IN($w[]) )'

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

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


来源:https://stackoverflow.com/questions/34878915/jq-how-to-select-objects-based-on-a-whitelist-of-property-values

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!