groupBy
Aman Aggarwal blogged about a powerful method from the
java.util.Collection class. The groupBy method converts a collection into a Map with the keys being returned by the closure passed to the method.Example:
def map = invoices.groupBy { it.invoiceDate.format("MM/yyyy") }
map.each { k, v ->
println "There are ${v.size()} invoices in ${k}"
}
Incidentally, the example above uses another cool function from
java.util.Date: format. The method takes a date pattern (from the specification of java.text.SimpleDateFormat) and returns a String.inject
While writing about
groupBy, I thought I might as well talk about the inject() method too. It is a method that is best explained with an example. If I want to add all the numbers from 1 until 10, i.e. 1 + 2 + 3 + 4 + ... + 10, I can do it in one line:
def sum = (1..10).inject(0) { a, b -> a += b }
0 is passed as the initial value. In each iteration, the value from the last iteration is passed as
a while the current value is passed as b. If we add a println statement, e.g.
def sum = (1..10).inject(0) { a, b ->
println "${a} + ${b} = ${a + b}"
a += b
}
The output will be:
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15
15 + 6 = 21
21 + 7 = 28
28 + 8 = 36
36 + 9 = 45
45 + 10 = 55
Another typical example is to calculate the product of a range of numbers. For example, to calculate the product of 1 to 10 (the factorial of 10):
def product = (1..10).inject(1) { a, b -> a *= b }
The result is the expected 3628800 (= 10!).