Reputation: 9928
The idiomatic way to check if a list contains something in Groovy is to use in
.
if ('b' in ['a', 'b', 'c'])
But how do you nicely check if something is not in a collection?
if (!('g' in ['a', 'b', 'c']))
Using logical not seems messy and the !
is hidden to the casual glance. Is there a more idiomatic way to do this in Groovy?
Thanks!
Upvotes: 69
Views: 73150
Reputation: 9586
Just for the sake of completeness, and for people reaching this thread post-2020, Groovy 3.0.0 introduced the !in
operator.
As per the OP example, it would be used like that:
if ('g' !in ['a','b','c'])
Upvotes: 27
Reputation: 11
What about disjoint
?
def elements = [1, 2, 3]
def element = 4
assert elements.disjoint([element])
element = 1
assert !elements.disjoint([element])
Bonus : it stops iterating when an element match
Upvotes: 0
Reputation: 8417
Regarding one of the original answers:
if (!['a', 'b', 'c'].contains('b'))
Somebody mentioned that it is easy to miss the ! because it's far from the method call. This can be solved by assigning the boolean result to a variable and just negate the variable.
def present = ['a', 'b', 'c'].contains('b')
if (!present) {
// do stuff
}
Upvotes: 1
Reputation: 3428
The contains(string) method is nice and simple to read if something is contained or not contained in the list to be checked against. Take a look the example below for more insight.
EXAMPLE
//Any data you are looking to filter
List someData = ['a', 'f', 'b', 'c', 'o', 'o']
//A filter/conditions to not match or match against
List myFilter = ['a', 'b', 'c']
//Some variables for this example
String filtered, unfiltered
//Loop the data and filter for not contains or contains
someData.each {
if (!myFilter.contains(it)){
unfiltered += it
} else {
filtered += it
}
}
assert unfiltered = "foo"
assert filtered = "abc"
CONTAINS( )
Parameters: text - a String to look for.
Returns: true if this string contains the given text
Upvotes: 0
Reputation: 141
You can add new functions:
Object.metaClass.notIn = { Object collection ->
!(delegate in collection)
}
assert "2".notIn(['1', '2q', '3'])
assert !"2".notIn(['1', '2', '3'])
assert 2.notIn([1, 3])
assert !2.notIn([1, 2, 3])
assert 2.notIn([1: 'a', 3: 'b'])
assert !2.notIn([1: 'a', 2: 'b'])
Upvotes: 14
Reputation: 1483
According to Grails documentation about creating criteria here, you can use something like this:
not {'in'("age",[18..65])}
In this example, you have a property named "age"
and you want to get rows that are NOT between 18 and 65. Of course, the [18..65]
part can be substituted with any list of values or range you need.
Upvotes: 1
Reputation: 19229
I think there is no not in
pretty syntax, unfortunately. But you can use a helper variable to make it more readable:
def isMagicChar = ch in ['a', 'b', 'c']
if (!isMagicChar) ...
Or, in this case, you may use a regex :)
if (ch !=~ /[abc]/) ...
Upvotes: 35
Reputation: 13122
More readable, I'm not sure:
assert ['a','b','c'].any{it == 'b'}
assert ['a','b','c'].every{it != 'g'}
For your example:
if (['a','b','c'].every{it != 'g'})
A few months ago, I suggested a new operator overloading ! (not operator). Now, maybe you can use any odd number of exclamations ;)
if(!!!('g' in ['a','b','c']))
Upvotes: 9
Reputation: 66099
Another way to write it is with contains
, e.g.
if (!['a', 'b', 'c'].contains('b'))
It saves the extra level of parentheses at the cost of replacing the operator with a method call.
Upvotes: 50