Skip to content
AgileLogics
6 min read

Working with Collections

Prerequisites: Closures, Lists, Maps

Groovy's collection methods take closures, so most loops become one line. These are the ones you'll use every day.

def prices = [12, 5, 30, 8, 20]

println prices.collect { it * 2 }          // transform each item
println prices.findAll { it > 10 }         // keep matching items
println prices.find { it > 10 }            // first match (or null)
println prices.any { it > 25 }             // does any match?
println prices.every { it > 1 }            // do all match?
println prices.count { it < 10 }           // how many match?
println prices.sum()
println prices.sort(false) { -it }         // sort by a key
[24, 10, 60, 16, 40]
[12, 30, 20]
12
true
true
2
75
[30, 20, 12, 8, 5]

each and eachWithIndex

def tasks = ['write', 'test', 'ship']

tasks.each { println "- $it" }

tasks.eachWithIndex { task, i ->
    println "${i + 1}. $task"
}
println tasks.withIndex().collect { t, i -> "$i:$t" }
- write
- test
- ship
1. write
2. test
3. ship
[0:write, 1:test, 2:ship]

Working with lists of maps

def people = [
    [name: 'Ada', age: 36, team: 'core'],
    [name: 'Linus', age: 28, team: 'kernel'],
    [name: 'Grace', age: 45, team: 'core'],
]

println people.findAll { it.team == 'core' }*.name
println people.max { it.age }.name
println people.sort(false) { it.age }*.name
println people.collectEntries { [it.name, it.age] }
println people.groupBy { it.team }.collectEntries { team, members -> [team, members.size()] }
[Ada, Grace]
Grace
[Linus, Ada, Grace]
[Ada:36, Linus:28, Grace:45]
[core:2, kernel:1]
  • collectEntries builds a map from [key, value] pairs.
  • groupBy builds a map from a key to the list of items with that key.
  • A trailing comma after the last list item is allowed.

Chaining

def words = 'the cat sat on the mat with the hat'.tokenize()

def result = words
    .findAll { it.size() == 3 }
    .collect { it.toUpperCase() }
    .unique()
    .sort()
    .join(', ')
println result
CAT, HAT, MAT, SAT, THE

Each method returns a new collection (except unique and sort, which change their receiver — safe here, because collect already made a new list).

Practice

From [3, 8, 12, 5, 20, 7], print the sum of the squares of the even numbers.

Show solution
def nums = [3, 8, 12, 5, 20, 7]
println nums.findAll { it % 2 == 0 }.collect { it * it }.sum()
608