Loading...

Thursday, December 16, 2010

Groovy Goodness: Transform String into Enum

After reading Groovy, State of the Union - Groovy Grails eXchange 2010 by Guillaume Laforge I discovered that in Groovy 1.7.6 we can transform a String into a Enum value. We can use type coersion or the as keyword to turn a String or GString into a corresponding Enum value (if possible).

enum Compass {
    NORTH, EAST, SOUTH, WEST
}

// Coersion with as keyword.
def north = 'NORTH' as Compass
assert north == Compass.NORTH

// Coersion by type.
Compass south = 'south'.toUpperCase()
assert south == Compass.SOUTH

def result = ['EA', 'WE'].collect {
    // Coersion of GString to Enum.
    "${it}ST" as Compass
}
assert result[0] == Compass.EAST
assert result[1] == Compass.WEST

Groovy Goodness: Determine Min and Max Entries in a Map

Since Groovy 1.7.6 we can use the min() and max() methods on a Map. We use a closure to define the condition for a minimum or maximum value. If we use two parameters in the closure we must do a classic comparison. We return a negative value if the first parameters is less than the second, zero if they are both equal, or a positive value if the first parameter is greater than the second parameter. If we use a single parameter we can return a value that is used as Comparable for determining the maximum or minimum entry in the Map.

def money = [cents: 5, dime: 2, quarter: 3]

// Determine max entry.
assert money.max { it.value }.value == 5
assert money.max { it.key }.key == 'quarter'  // Use String comparison for key.
assert money.max { a, b ->
    a.key.size() <=> b.key.size() 
}.key == 'quarter'  // Use Comparator and compare key size.

// Determine min entry.
assert money.min { it.value }.value == 2
assert money.min { it.key }.key == 'cents'  // Use String comparison for key.
assert money.min { a, b ->
    a.key.size() <=> b.key.size() 
}.key == 'dime'  // Use Comparator and compare key size.

Groovy Goodness: Use Map in Switch Statement

Since Groovy 1.7.6 we can use a Map as a case in a switch statement. Groovy adds the isCase() method where the switch operand is used to find map elements. Groovy tries to find a key with the given switch operand in the Map and if it is found true is returned.

def testSwitch(val) {
    def result
    switch (val) {
        // New in Groovy 1.7.6: Map support.
        case [groovy: 'Rocks!', version: '1.7.6']:
            result = "Map contains key '$val'"
            break
        case 60..90:
            result = "Range contains $val"
            break
        case [21, 'test', 9.12]:
            result = "List contains '$val'"
            break
        default:
            result = 'Default'
            break
    }    
    result
}

assert testSwitch('groovy') == "Map contains key 'groovy'"
assert testSwitch(70) == 'Range contains 70'
assert testSwitch('test') == "List contains 'test'"
assert testSwitch('default') == 'Default'

Groovy Goodness: Convert Date to Calendar

In Groovy version 1.7.6 we can convert a Date to a Calendar with the toCalendar() method. The toCalendar() method is added to the Date class by Groovy.

import static java.util.Calendar.*

def date = new Date()
date.set year: 2010, month: 11, date: 16

def calendar = date.toCalendar()

assert calendar[YEAR] == 2010
assert calendar[MONTH] == Calendar.DECEMBER
assert calendar[DATE] == 16
assert calendar.format('dd-MM-yyyy') == '16-12-2010'
assert calendar in Calendar

Saturday, December 11, 2010

Groovy Goodness: Find First Non-Null Result From a Closure

A new feature from Groovy 1.8 (according to the Javadoc it is available since 1.8) is already available in Groovy 1.7.5. With the method findResult() we iterate through an object and find the first non-null result from a closure. We can even define a default value if there is no non-null result.

def list = ['Groovy', 'Griffon', 'Grails', 'Gradle']

assert list.findResult { it.startsWith('Gra') ? it : null } == 'Grails'
assert list.findResult('Gr8') { 
    if (it.size() < 6) {
        "found text with size smaller than 6"
    }
} == 'Gr8'

Wednesday, December 1, 2010

Groovy Goodness: Invoke Anonymous Closure

Groovy closures can be invoked directly after we have defined them. This way we get the result immediately and can assign it to a variable. We use call() or () after we have defined the closure, so the closure code is executed and the return value of the closure is assigned to the variable.

def date = {
    def d = new Date()
    d.set year: 2010, month: Calendar.DECEMBER, date: 1
    d.format "dd-MM-yyyy"
}()

assert date == '01-12-2010'

def text = {
    def result = ''
    "mrhaki".size().times {
        result += it
    }
    result
}.call()

assert text == '012345'