Simon Schiller
Simon Schiller

Reputation: 664

Groovy: More elegant way to achieve this?

I have following groovy function:

def getDependantLibs(updatedLib) {
    def dependants = []
    getAllLibs().each { lib ->
        try {
            def ref = getFromStash("/repos/${lib}/dependencies.json").find { it.name == updatedLib }
            if (ref != null) {
                dependants.add([ name: lib, version: ref.version ])
            }
        } catch (err) {}
    }
    return dependants
}

My question is, can I achieve this in a more elegant way (maybe with groovy Collecion functions like collect, flatten, ...)

Upvotes: 1

Views: 2046

Answers (2)

Szymon Stepniak
Szymon Stepniak

Reputation: 42184

Instead of using Collection.each(Closure closure) you can utilize Collection.collect(Closure transform) for transforming each element of the list from one format to another and Collection.findAll(Closure predicate) to filter null elements from final list. Something like this:

def getDependantLibs(updatedLib) {
    return getAllLibs().collect { lib ->
        try {
            [lib: lib, ref: getFromStash("/repos/${lib}/dependencies.json").find { it.name == updatedLib }]
        } catch (err) {
            [lib: lib, ref: null]
        }
    }.findAll { it.ref != null }.collect { [name: it.lib, version: it.ref.version] }
}

Using Java 8 Stream API

You can always use Java 8 Stream API with Groovy. The main advantage of using Stream API in this case is that all operations on stream are lazy - they are executed when reduction function is called. It means that you can apply n-number of transformations and only one iteration will be triggered. In Groovy if you apply let's say 3 bulk collection methods, Groovy will iterate 3 times.

Below you can find an example of using Java 8 Stream API in Groovy:

def getDependantLibsWithStream(updatedLib) {
    return getAllLibs().stream()
            .map({ lib ->
                try {
                    [lib: lib, ref: getFromStash("/repos/${lib}/dependencies.json").find { it.name == updatedLib }]
                } catch (err) {
                    [lib: lib, ref: null]
                }
            })
            .filter({ it.ref != null })
            .map({ [name: it.lib, version: it.ref.version] })
            .collect(Collectors.toList())
}

I hope it helps.

Upvotes: 0

cfrick
cfrick

Reputation: 37008

Yes, you can use collectMany. E.g.:

def deps = [1,2,3,4]
println deps.collectMany{
    try {
        if (it&1) {
            throw new RuntimeException(it.toString())
        }
        (0..it).collect{
            [x: it]
        }
    }
    catch (Exception e) {
        println "failed: $e.message"
        return []
    }
}
// output:
// failed: 1
// failed: 3
// [[x:0], [x:1], [x:2], [x:0], [x:1], [x:2], [x:3], [x:4]]

Upvotes: 1

Related Questions