Groovy's Inject

Java

When I started getting into functional programming I relaized that Groovy has some features which could be considered functional or higher-order functions. I commonly use methods like findAll (filter) and collect (map). As I was reading Beginning Scala by David Pollack I came across fold which I had never used before. Groovy calls this inject. inject allows us to walk though a data structure calling a function on each node, the result of that function is then passed to the same function being called on the next node.

Here are a few examples

assert 55 == (1..10).inject(0) { a,b-> a + b }

// which is the same as
assert 55 == 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10

// Say we wanted to map lower case characters to their upper case brothers
List alphabetLower = ['a', 'b', 'c', 'd', 'e']

Map alphabetMap = [:]
alphabetLower.each {letter->
    alphabetMap.put(letter, letter.toUpperCase())
}

// We can rerwite that as 
Map alphabetMap = alphabetLower.inject([:]) {map, letter->
    map.put(letter, letter.toUpperCase())
}


Answering a fizzbuzz like this will not get you the job.

print (1..100).inject(""){s,i->s+="$i-${i%3?'':'fizz'}${i%5?'':'buzz'}\n"} 

Pimp Groovy’s List

Groovy’s inject is considered a fold left since we work our way left to right. Groovy doesn’t provide a fold right, however we can pimp java the same way Groovy does.

class FoldRight {
    static Object foldRight(List self, Object initalValue, Closure closure) {
        Object value = initalValue
        for (ListIterator iterator = self.listIterator(self.size()); iterator.hasPrevious();) {
            Object node = iterator.previous()
            value = closure.call(value, node)
        }
        return value
    }

    static Object injectRight(List self, Object initalValue, Closure closure) {
        foldRight(self, initalValue, closure)
    }
}

// Test it
use(FoldRight) {
    assert "dcba" == ['a','b','c','d'].foldRight("") {a,b-> a+b }
    assert "dcba" == ['a','b','c','d'].injectRight("") {a,b-> a+b }
}