Groovy Gotcha With the Every() Collection Method

Groovy Add comments

In the Groovy programming language, every object that implements the Iterable interface (such as List and Map objects) comes with the every() method.  The every() method takes a closure as an argument and is supposed to evaluate whether every item in the collection meets the condition set forth in the closure:

assert [ 3, 4 ].every{ element -> element > 2 }  //true
assert [ fingerCount: 10, toeCount: 10 ].every{ key, value -> value == 10 } //true

Given that, you might reasonably expect that the every() method would return false when executed against an empty collection. But it doesn't:

assert [].every{ element -> element > 2 }  //true
assert [ : ].every{ key, value -> value == 10 }  //true 

There is a JIRA ticket about this issue: The initial commenter's guess is probably correct: that the every() method starts with a default return value of true and only becomes false if and when an item in the collection fails the conditional test, so an empty collection fails to affect the default value of true.

Still, it's not what I would have expected, and I was unaware of the behavior until I encountered it for myself.

3 responses to “Groovy Gotcha With the Every() Collection Method”

  1. Ryan Guill Says:
    FYI this is consistent with other languages - JS & c# for a couple examples

    The main reason is that `every(f) == !some(f)`
  2. Brian C Swartzfager Says:
    @Ryan: I appreciate that, but it's still counter-intuitive. At least in both of those documentation links you provided, it states that an empty set will return true: that's not currently the case in the Groovy documentation.
  3. No Bugs Says:
    This is consistent with formal logic: The statement "P implies Q" is always true unless we have a specific case where P is true and Q is false. In the case when P is itself false, no such counterexample can be produced so the implication is true in such cases.

Leave a Reply