Finding Items in a Collection

To find all items matching a condition in a collection, use the findAll() function. It accepts a boolean closure identifying the items you're looking for.

The result is a List of all items in the collection for which the closure evaluates to true. If no item matches or the collection is empty, then an empty collection is returned.

As shown below, you can leave off the parentheses if passing the closure in-line. The result of this example is a list containing all recipient emails whose address ends with the .edu suffix:
def recipients = ['sjc@example.edu','dan@example.com',
                  'spm@example.edu','jim@example.org']
// Pass boolean closure using implicit "it" parameter with find criteria
// (using safe-navigation operator in case any element is null)
def eduAddreses = recipients.findAll{ it?.endsWith('.edu') }

When applied to a List of Map objects, your closure can reference the current map's keys by name as shown below. This example produces a list of phonebook entries having a phone number that starts with the country code "+39-" for Italy.

def phonebook = [
                    [name: 'Steve', phone: '+39-123456789'],
                    [name: 'Joey',  phone: '+1-234567890'],
                    [name: 'Sara',  phone: '+39-345678901'],
                    [name: 'Zoe',   phone: '+44-456789123']   
                 ]
def italianFriends = phonebook.findAll { it?.phone?.startsWith('+39-') }
If you call findAll() on a Map, then the parameter passed to the closure on each evaluation is the current Map entry. Each entry has a key and value property you can reference in the closure function body if necessary. The result is a Map containing only the entries for which the closure evaluates to true. In the example below, the result is a map containing the two users' map entries whose name is Steve.
def users = [
             'smuench':[name:'Steve', badge:'A123'],
             'jevans':[name:'Joe', badge:'B456'],
             'sburns':[name:'Steve', badge:'C789']
            ]
def usersNamedSteve = users.findAll { it?.value.name == 'Steve' }
To find only the first matching item, use the find() function instead of findAll(). It accepts the same boolean closure but stops when the first match is identified. Note that in contrast to findAll(), when using find() if no item matches the predicate or the collection was empty to begin with then null is returned.

Companion functions exist to perform other searching operations like:

  • any { boolean_predicate } — returns true if boolean_predicate returns true for any item
  • every { boolean_predicate } — returns true if boolean_predicate returns true for every item