Groovy Functional Programming - Collect

Functional programming languages provide a map higher order function, which produces a new collection by applying the specified function on each element of the collection on which the map operation is invoked. Groovy uses collect instead of map.

Consider the following list of numbers.

def numbers = [1, 2, 3, 4]

Let's create a closure which takes a number and returns number + 1

def increment = { number ->
    number + 1
}
If you are not familiar with the concept of pure functions, this post has the details.

Now we can apply this increment mapping (transformation) on each of the element in the list numbers.
An imperative solutions would look as follows

numbersIncrementedByOne = []
for(number in numbers) {
    numbersIncrementedByOne << increment(number)
}

Similarly, let's create another closure to calculate the square of a number and compute the square of each number in the list of numbers.

def square = { number ->
    number * number
}

squaresOfNumbers = []
for(number in numbers) {
    squaresOfNumbers << square(number)
}

I hope you can recognise the pattern in applying increment and square. We can generalise this solution by creating a function that accepts a transformation closure and creates a new collection by applying the closure on each of the element. This function is readily available in Groovy with the name collect. Let's refactor the above code to make use of collect.

numbersIncrementedByOne  = numbers.collect(increment) // returns [2, 3, 4, 5]
squaresOfNumbers  = numbers.collect(square) // returns [1, 4, 9, 16]

You may want to take a look at the slides from my FunctionalConf talk for more examples.

Show Comments