Code, Compose, Bike, Brew


…though not necessarily in that order

Conditionally Collecting Objects in Groovy

| Comments

Groovy’s Collections collect() method is great for iterating a collection and generating a new collection containing transformed results. For example:

import groovy.transform.Immutable

// Define a 'User' class
@Immutable
class User {
  String firstName
  String lastName
  boolean administrator
}

// Create a couple of users
def users = [new User("Edd", "Grant", true), new User("Jon", "Doe", false)]

// Use collect() to generate a list of their full names
def fullNames = users.collect() { user ->
  "${user.firstName} ${user.lastName}"
}

assert ["Edd Grant", "Jon Doe"] == fullNames

Sometimes, however, what we really want is something more akin to ‘collect where some criteria is met’. collect() doesn’t provide a mechanism for doing this, because this functionality is provided by a different method: Groovy implements the findResults method which collects only non-null results, this allows us to filter the source collection really easily. For example:

import groovy.transform.Immutable

// Define a 'User' class
@Immutable
class User {
  String firstName
  String lastName
  boolean administrator
}

// Create a couple of users
def edd = new User("Edd", "Grant", true)
def users = [edd, new User("Jon", "Doe", false)]

// Use findResults() to generate a list of administrators
def administrators = users.findResults() { user ->
  user.administrator ? user : null
}

assert [edd] == administrators

collect() has been around since v1.8.5 whereas findResults() is a more recent addition, being introduced in v2.2.0.

Comments