flatten()

I post this because, as I continue to learn Goovy/Grails, I keep getting stuck on stupid problems that should be simple.

I needed to count the number of items in a nested collection. I thought that the Groovy spread operator would give me the solution, but it didn’t. At work I just went for the easy option of nested each construction incrementing a counter. Messy, but I really don’t have time to dick around and it gave me a working solution.

So this evening I spent some time on the problem and discovered this, perhaps obvious, easy solution. The unit test below illustrates this.

import spock.lang.*
import grails.test.mixin.*

@Mock([Employee, Company, CompanyGroup])
class CompanyGroupSpec extends Specification {

	void "Test spread"() {
		
		when: "We have a group of companies with employees"
		
		Employee alice = new Employee(employeeName: 'Alice')
		Employee bob = new Employee(employeeName: 'Bob')
		Company acme = new Company(companyName: 'Acme')
		acme.addToEmployees(alice)
		acme.addToEmployees(bob)
		
		Employee claire = new Employee(employeeName: 'Claire')
		Employee dave = new Employee(employeeName: 'Dave')
		Company bravo = new Company(companyName: 'Bravo')
		bravo.addToEmployees(claire)
		bravo.addToEmployees(dave)
		
		CompanyGroup group = new CompanyGroup(groupName: 'Super Group')
		group.addToCompanies(acme)
		group.addToCompanies(bravo)
		
		then: "spread gives unexpected results"
		
		acme.employees.size() == 2
		bravo.employees.size() == 2
		
		group*.companies*.employees.size() == 1
		
		group*.companies*.employees.flatten().size() == 4
		
	}
	
}

As you can see, I want a count of the number of employees in all companies in the group. I expected four. If the map isn’t flattened then I end up with a count of outer container, which is always one.

I hope this snippet has saved you enough time to treat yourself to a coffee :-)

Flattr this!